packages feed

jvm-binary 0.1.0 → 0.2.0

raw patch · 27 files changed

+1015/−204 lines, 27 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Language.JVM.ClassFileReader: instance Control.Monad.Reader.Class.MonadReader (GHC.Base.String, Language.JVM.ConstantPool.ConstantPool Language.JVM.Stage.High) Language.JVM.ClassFileReader.Evolve
+ Language.JVM.AccessFlag: ICAbstract :: ICAccessFlag
+ Language.JVM.AccessFlag: ICAnnotation :: ICAccessFlag
+ Language.JVM.AccessFlag: ICEnum :: ICAccessFlag
+ Language.JVM.AccessFlag: ICFinal :: ICAccessFlag
+ Language.JVM.AccessFlag: ICInterface :: ICAccessFlag
+ Language.JVM.AccessFlag: ICPrivate :: ICAccessFlag
+ Language.JVM.AccessFlag: ICProtected :: ICAccessFlag
+ Language.JVM.AccessFlag: ICPublic :: ICAccessFlag
+ Language.JVM.AccessFlag: ICStatic :: ICAccessFlag
+ Language.JVM.AccessFlag: ICSynthetic :: ICAccessFlag
+ Language.JVM.AccessFlag: data ICAccessFlag
+ Language.JVM.AccessFlag: icflags :: [(Int, ICAccessFlag)]
+ Language.JVM.AccessFlag: instance Control.DeepSeq.NFData Language.JVM.AccessFlag.ICAccessFlag
+ Language.JVM.AccessFlag: instance GHC.Classes.Eq Language.JVM.AccessFlag.ICAccessFlag
+ Language.JVM.AccessFlag: instance GHC.Classes.Ord Language.JVM.AccessFlag.ICAccessFlag
+ Language.JVM.AccessFlag: instance GHC.Generics.Generic Language.JVM.AccessFlag.ICAccessFlag
+ Language.JVM.AccessFlag: instance GHC.Show.Show Language.JVM.AccessFlag.ICAccessFlag
+ Language.JVM.AccessFlag: instance Language.JVM.Utils.Enumish Language.JVM.AccessFlag.ICAccessFlag
+ Language.JVM.Attribute.EnclosingMethod: EnclosingMethod :: !(Ref ClassName r) -> !(Ref (Maybe MethodId) r) -> EnclosingMethod r
+ Language.JVM.Attribute.EnclosingMethod: [enclosingClassName] :: EnclosingMethod r -> !(Ref ClassName r)
+ Language.JVM.Attribute.EnclosingMethod: [enclosingMethodName] :: EnclosingMethod r -> !(Ref (Maybe MethodId) r)
+ Language.JVM.Attribute.EnclosingMethod: data EnclosingMethod r
+ Language.JVM.Attribute.EnclosingMethod: instance Control.DeepSeq.NFData (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.EnclosingMethod: instance Control.DeepSeq.NFData (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.EnclosingMethod: instance Data.Binary.Class.Binary (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.EnclosingMethod: instance GHC.Classes.Eq (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.EnclosingMethod: instance GHC.Classes.Eq (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.EnclosingMethod: instance GHC.Classes.Ord (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.EnclosingMethod: instance GHC.Generics.Generic (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.EnclosingMethod: instance GHC.Generics.Generic (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.EnclosingMethod: instance GHC.Show.Show (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.High)
+ Language.JVM.Attribute.EnclosingMethod: instance GHC.Show.Show (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.EnclosingMethod: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.EnclosingMethod.EnclosingMethod Language.JVM.Stage.Low)
+ Language.JVM.Attribute.EnclosingMethod: instance Language.JVM.Staged.Staged Language.JVM.Attribute.EnclosingMethod.EnclosingMethod
+ Language.JVM.Attribute.InnerClasses: InnerClass :: !(Ref ClassName r) -> !(Ref (Maybe ClassName) r) -> !(Ref (Maybe Text) r) -> !(BitSet16 ICAccessFlag) -> InnerClass r
+ Language.JVM.Attribute.InnerClasses: InnerClasses :: Choice (SizedList16 (InnerClass Low)) [InnerClass High] r -> InnerClasses r
+ Language.JVM.Attribute.InnerClasses: [icClassName] :: InnerClass r -> !(Ref ClassName r)
+ Language.JVM.Attribute.InnerClasses: [icInnerAccessFlags] :: InnerClass r -> !(BitSet16 ICAccessFlag)
+ Language.JVM.Attribute.InnerClasses: [icInnerName] :: InnerClass r -> !(Ref (Maybe Text) r)
+ Language.JVM.Attribute.InnerClasses: [icOuterClassName] :: InnerClass r -> !(Ref (Maybe ClassName) r)
+ Language.JVM.Attribute.InnerClasses: [innerClasses] :: InnerClasses r -> Choice (SizedList16 (InnerClass Low)) [InnerClass High] r
+ Language.JVM.Attribute.InnerClasses: data InnerClass r
+ Language.JVM.Attribute.InnerClasses: instance Control.DeepSeq.NFData (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance Control.DeepSeq.NFData (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance Control.DeepSeq.NFData (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance Control.DeepSeq.NFData (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance Data.Binary.Class.Binary (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance Data.Binary.Class.Binary (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Classes.Eq (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Classes.Eq (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Classes.Eq (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Classes.Eq (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Classes.Ord (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Classes.Ord (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Generics.Generic (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Generics.Generic (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Generics.Generic (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Generics.Generic (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Show.Show (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Show.Show (Language.JVM.Attribute.InnerClasses.InnerClass Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Show.Show (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.High)
+ Language.JVM.Attribute.InnerClasses: instance GHC.Show.Show (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance Language.JVM.Attribute.Base.IsAttribute (Language.JVM.Attribute.InnerClasses.InnerClasses Language.JVM.Stage.Low)
+ Language.JVM.Attribute.InnerClasses: instance Language.JVM.Staged.Staged Language.JVM.Attribute.InnerClasses.InnerClass
+ Language.JVM.Attribute.InnerClasses: instance Language.JVM.Staged.Staged Language.JVM.Attribute.InnerClasses.InnerClasses
+ Language.JVM.Attribute.InnerClasses: newtype InnerClasses r
+ Language.JVM.Attribute.Signature: BaseType :: JBaseType -> TypeSignature
+ Language.JVM.Attribute.Signature: ClassSignature :: [TypeParameter] -> ClassType -> [ClassType] -> ClassSignature
+ Language.JVM.Attribute.Signature: ClassType :: ClassName -> [Maybe TypeArgument] -> ClassType
+ Language.JVM.Attribute.Signature: FieldSignature :: ReferenceType -> FieldSignature
+ Language.JVM.Attribute.Signature: InnerClassType :: Text -> ClassType -> [Maybe TypeArgument] -> ClassType
+ Language.JVM.Attribute.Signature: MethodSignature :: [TypeParameter] -> [TypeSignature] -> Maybe TypeSignature -> [ThrowsSignature] -> MethodSignature
+ Language.JVM.Attribute.Signature: RefArrayType :: TypeSignature -> ReferenceType
+ Language.JVM.Attribute.Signature: RefClassType :: ClassType -> ReferenceType
+ Language.JVM.Attribute.Signature: RefTypeVariable :: TypeVariable -> ReferenceType
+ Language.JVM.Attribute.Signature: ReferenceType :: ReferenceType -> TypeSignature
+ Language.JVM.Attribute.Signature: ThrowsClass :: ClassType -> ThrowsSignature
+ Language.JVM.Attribute.Signature: ThrowsTypeVariable :: TypeVariable -> ThrowsSignature
+ Language.JVM.Attribute.Signature: TypeArgument :: Maybe Wildcard -> ReferenceType -> TypeArgument
+ Language.JVM.Attribute.Signature: TypeParameter :: Text -> Maybe ReferenceType -> [ReferenceType] -> TypeParameter
+ Language.JVM.Attribute.Signature: TypeVariable :: Text -> TypeVariable
+ Language.JVM.Attribute.Signature: WildMinus :: Wildcard
+ Language.JVM.Attribute.Signature: WildPlus :: Wildcard
+ Language.JVM.Attribute.Signature: [csInterfaceSignatures] :: ClassSignature -> [ClassType]
+ Language.JVM.Attribute.Signature: [csSuperclassSignature] :: ClassSignature -> ClassType
+ Language.JVM.Attribute.Signature: [csTypeParameters] :: ClassSignature -> [TypeParameter]
+ Language.JVM.Attribute.Signature: [ctsClassName] :: ClassType -> ClassName
+ Language.JVM.Attribute.Signature: [ctsInnerClassName] :: ClassType -> Text
+ Language.JVM.Attribute.Signature: [ctsOuterClassType] :: ClassType -> ClassType
+ Language.JVM.Attribute.Signature: [ctsTypeArguments] :: ClassType -> [Maybe TypeArgument]
+ Language.JVM.Attribute.Signature: [fsRefType] :: FieldSignature -> ReferenceType
+ Language.JVM.Attribute.Signature: [msArguments] :: MethodSignature -> [TypeSignature]
+ Language.JVM.Attribute.Signature: [msResults] :: MethodSignature -> Maybe TypeSignature
+ Language.JVM.Attribute.Signature: [msThrows] :: MethodSignature -> [ThrowsSignature]
+ Language.JVM.Attribute.Signature: [msTypeParameters] :: MethodSignature -> [TypeParameter]
+ Language.JVM.Attribute.Signature: [taType] :: TypeArgument -> ReferenceType
+ Language.JVM.Attribute.Signature: [taWildcard] :: TypeArgument -> Maybe Wildcard
+ Language.JVM.Attribute.Signature: [tpClassBound] :: TypeParameter -> Maybe ReferenceType
+ Language.JVM.Attribute.Signature: [tpIndentifier] :: TypeParameter -> Text
+ Language.JVM.Attribute.Signature: [tpInterfaceBound] :: TypeParameter -> [ReferenceType]
+ Language.JVM.Attribute.Signature: [tvAsText] :: TypeVariable -> Text
+ Language.JVM.Attribute.Signature: classSignatureFromText :: Text -> Either String ClassSignature
+ Language.JVM.Attribute.Signature: classSignatureP :: Parser ClassSignature
+ Language.JVM.Attribute.Signature: classSignatureToText :: ClassSignature -> Text
+ Language.JVM.Attribute.Signature: classTypeP :: Parser ClassType
+ Language.JVM.Attribute.Signature: data ClassSignature
+ Language.JVM.Attribute.Signature: data ClassType
+ Language.JVM.Attribute.Signature: data MethodSignature
+ Language.JVM.Attribute.Signature: data ReferenceType
+ Language.JVM.Attribute.Signature: data ThrowsSignature
+ Language.JVM.Attribute.Signature: data TypeArgument
+ Language.JVM.Attribute.Signature: data TypeParameter
+ Language.JVM.Attribute.Signature: data TypeSignature
+ Language.JVM.Attribute.Signature: data Wildcard
+ Language.JVM.Attribute.Signature: fieldSignatureFromText :: Text -> Either String FieldSignature
+ Language.JVM.Attribute.Signature: fieldSignatureP :: Parser FieldSignature
+ Language.JVM.Attribute.Signature: fieldSignatureToText :: FieldSignature -> Text
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.ClassSignature
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.ClassType
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.FieldSignature
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.MethodSignature
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.ReferenceType
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.ThrowsSignature
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.TypeArgument
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.TypeParameter
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.TypeSignature
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.TypeVariable
+ Language.JVM.Attribute.Signature: instance Control.DeepSeq.NFData Language.JVM.Attribute.Signature.Wildcard
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.ClassSignature
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.ClassType
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.FieldSignature
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.MethodSignature
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.ReferenceType
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.ThrowsSignature
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.TypeArgument
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.TypeParameter
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.TypeSignature
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.TypeVariable
+ Language.JVM.Attribute.Signature: instance GHC.Classes.Eq Language.JVM.Attribute.Signature.Wildcard
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.ClassSignature
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.ClassType
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.FieldSignature
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.MethodSignature
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.ReferenceType
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.ThrowsSignature
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.TypeArgument
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.TypeParameter
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.TypeSignature
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.TypeVariable
+ Language.JVM.Attribute.Signature: instance GHC.Generics.Generic Language.JVM.Attribute.Signature.Wildcard
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.ClassSignature
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.ClassType
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.FieldSignature
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.MethodSignature
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.ReferenceType
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.ThrowsSignature
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.TypeArgument
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.TypeParameter
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.TypeSignature
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.TypeVariable
+ Language.JVM.Attribute.Signature: instance GHC.Show.Show Language.JVM.Attribute.Signature.Wildcard
+ Language.JVM.Attribute.Signature: methodSignatureFromText :: Text -> Either String MethodSignature
+ Language.JVM.Attribute.Signature: methodSignatureP :: Parser MethodSignature
+ Language.JVM.Attribute.Signature: methodSignatureToText :: MethodSignature -> Text
+ Language.JVM.Attribute.Signature: newtype FieldSignature
+ Language.JVM.Attribute.Signature: newtype TypeVariable
+ Language.JVM.Attribute.Signature: referenceTypeP :: Parser ReferenceType
+ Language.JVM.Attribute.Signature: typeParameterP :: Parser TypeParameter
+ Language.JVM.Attribute.Signature: typeParametersP :: Parser [TypeParameter]
+ Language.JVM.Attribute.Signature: typeVariableP :: Parser TypeVariable
+ Language.JVM.ClassFile: [caEnclosingMethod] :: ClassAttributes r -> [EnclosingMethod r]
+ Language.JVM.ClassFile: [caInnerClasses] :: ClassAttributes r -> [InnerClasses r]
+ Language.JVM.ClassFile: cEnclosingMethod :: ClassFile High -> Maybe (EnclosingMethod High)
+ Language.JVM.ClassFile: cInnerClasses :: ClassFile High -> [InnerClass High]
+ Language.JVM.ClassFileReader: EvolveConfig :: [String] -> ConstantPool High -> ((AttributeLocation, Text) -> Bool) -> EvolveConfig
+ Language.JVM.ClassFileReader: [ecAttributeFilter] :: EvolveConfig -> ((AttributeLocation, Text) -> Bool)
+ Language.JVM.ClassFileReader: [ecConstantPool] :: EvolveConfig -> ConstantPool High
+ Language.JVM.ClassFileReader: [ecLabel] :: EvolveConfig -> [String]
+ Language.JVM.ClassFileReader: data EvolveConfig
+ Language.JVM.ClassFileReader: instance Control.Monad.Reader.Class.MonadReader Language.JVM.ClassFileReader.EvolveConfig Language.JVM.ClassFileReader.Evolve
+ Language.JVM.Staged: ClassAttribute :: AttributeLocation
+ Language.JVM.Staged: CodeAttribute :: AttributeLocation
+ Language.JVM.Staged: FieldAttribute :: AttributeLocation
+ Language.JVM.Staged: MethodAttribute :: AttributeLocation
+ Language.JVM.Staged: attributeFilter :: EvolveM m => m ((AttributeLocation, Text) -> Bool)
+ Language.JVM.Staged: data AttributeLocation
+ Language.JVM.Staged: instance GHC.Classes.Eq Language.JVM.Staged.AttributeLocation
+ Language.JVM.Staged: instance GHC.Classes.Ord Language.JVM.Staged.AttributeLocation
+ Language.JVM.Staged: instance GHC.Show.Show Language.JVM.Staged.AttributeLocation
+ Language.JVM.Type: jBaseTypeP :: Parser JBaseType
+ Language.JVM.Type: jBaseTypeToChar :: JBaseType -> Char
- Language.JVM.Attribute.Base: fromAttributes :: (Foldable f, EvolveM m, Monoid a) => (Attribute High -> m a) -> f (Attribute Low) -> m a
+ Language.JVM.Attribute.Base: fromAttributes :: (Foldable f, EvolveM m, Monoid a) => AttributeLocation -> (Attribute High -> m a) -> f (Attribute Low) -> m a
- Language.JVM.ByteCode: ArrayLoad :: ArrayType -> ByteCodeOpr r
+ Language.JVM.ByteCode: ArrayLoad :: !ArrayType -> ByteCodeOpr r
- Language.JVM.ByteCode: ArrayStore :: ArrayType -> ByteCodeOpr r
+ Language.JVM.ByteCode: ArrayStore :: !ArrayType -> ByteCodeOpr r
- Language.JVM.ByteCode: BinaryOpr :: BinOpr -> ArithmeticType -> ByteCodeOpr r
+ Language.JVM.ByteCode: BinaryOpr :: !BinOpr -> !ArithmeticType -> ByteCodeOpr r
- Language.JVM.ByteCode: BitOpr :: BitOpr -> WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: BitOpr :: !BitOpr -> !WordSize -> ByteCodeOpr r
- Language.JVM.ByteCode: Cast :: CastOpr -> ByteCodeOpr r
+ Language.JVM.ByteCode: Cast :: !CastOpr -> ByteCodeOpr r
- Language.JVM.ByteCode: CheckCast :: (Ref ClassName r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: CheckCast :: !(Ref ClassName r) -> ByteCodeOpr r
- Language.JVM.ByteCode: CompareFloating :: Bool -> WordSize -> ByteCodeOpr r
+ Language.JVM.ByteCode: CompareFloating :: !Bool -> !WordSize -> ByteCodeOpr r
- Language.JVM.ByteCode: EARef :: (Ref ClassName r) -> ExactArrayType r
+ Language.JVM.ByteCode: EARef :: !(Ref ClassName r) -> ExactArrayType r
- Language.JVM.ByteCode: Get :: FieldAccess -> (DeepRef (InClass FieldId) r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Get :: !FieldAccess -> !(DeepRef (InClass FieldId) r) -> ByteCodeOpr r
- Language.JVM.ByteCode: Goto :: (LongRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Goto :: !(LongRelativeRef r) -> ByteCodeOpr r
- Language.JVM.ByteCode: If :: CmpOpr -> OneOrTwo -> (ShortRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: If :: !CmpOpr -> !OneOrTwo -> !(ShortRelativeRef r) -> ByteCodeOpr r
- Language.JVM.ByteCode: IfRef :: Bool -> OneOrTwo -> (ShortRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: IfRef :: !Bool -> !OneOrTwo -> !(ShortRelativeRef r) -> ByteCodeOpr r
- Language.JVM.ByteCode: InstanceOf :: (Ref ClassName r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: InstanceOf :: !(Ref ClassName r) -> ByteCodeOpr r
- Language.JVM.ByteCode: InvkDynamic :: (DeepRef InvokeDynamic r) -> Invocation r
+ Language.JVM.ByteCode: InvkDynamic :: !(DeepRef InvokeDynamic r) -> Invocation r
- Language.JVM.ByteCode: InvkInterface :: Word8 -> (DeepRef AbsInterfaceMethodId r) -> Invocation r
+ Language.JVM.ByteCode: InvkInterface :: !Word8 -> !(DeepRef AbsInterfaceMethodId r) -> Invocation r
- Language.JVM.ByteCode: InvkSpecial :: (DeepRef AbsVariableMethodId r) -> Invocation r
+ Language.JVM.ByteCode: InvkSpecial :: !(DeepRef AbsVariableMethodId r) -> Invocation r
- Language.JVM.ByteCode: InvkStatic :: (DeepRef AbsVariableMethodId r) -> Invocation r
+ Language.JVM.ByteCode: InvkStatic :: !(DeepRef AbsVariableMethodId r) -> Invocation r
- Language.JVM.ByteCode: InvkVirtual :: (DeepRef AbsMethodId r) -> Invocation r
+ Language.JVM.ByteCode: InvkVirtual :: !(DeepRef AbsMethodId r) -> Invocation r
- Language.JVM.ByteCode: Invoke :: (Invocation r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Invoke :: !(Invocation r) -> ByteCodeOpr r
- Language.JVM.ByteCode: Jsr :: (LongRelativeRef r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Jsr :: !(LongRelativeRef r) -> ByteCodeOpr r
- Language.JVM.ByteCode: Load :: LocalType -> LocalAddress -> ByteCodeOpr r
+ Language.JVM.ByteCode: Load :: !LocalType -> !LocalAddress -> ByteCodeOpr r
- Language.JVM.ByteCode: LookupSwitch :: Int32 -> (Vector (Int32, Int32)) -> ByteCodeOpr r
+ Language.JVM.ByteCode: LookupSwitch :: !Int32 -> (Vector (Int32, Int32)) -> ByteCodeOpr r
- Language.JVM.ByteCode: Monitor :: Bool -> ByteCodeOpr r
+ Language.JVM.ByteCode: Monitor :: !Bool -> ByteCodeOpr r
- Language.JVM.ByteCode: MultiNewArray :: (Ref ClassName r) -> Word8 -> ByteCodeOpr r
+ Language.JVM.ByteCode: MultiNewArray :: !(Ref ClassName r) -> !Word8 -> ByteCodeOpr r
- Language.JVM.ByteCode: Neg :: ArithmeticType -> ByteCodeOpr r
+ Language.JVM.ByteCode: Neg :: !ArithmeticType -> ByteCodeOpr r
- Language.JVM.ByteCode: New :: (Ref ClassName r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: New :: !(Ref ClassName r) -> ByteCodeOpr r
- Language.JVM.ByteCode: NewArray :: (ExactArrayType r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: NewArray :: !(ExactArrayType r) -> ByteCodeOpr r
- Language.JVM.ByteCode: Push :: (BConstant r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Push :: !(BConstant r) -> ByteCodeOpr r
- Language.JVM.ByteCode: Put :: FieldAccess -> (DeepRef (InClass FieldId) r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Put :: !FieldAccess -> !(DeepRef (InClass FieldId) r) -> ByteCodeOpr r
- Language.JVM.ByteCode: Ret :: LocalAddress -> ByteCodeOpr r
+ Language.JVM.ByteCode: Ret :: !LocalAddress -> ByteCodeOpr r
- Language.JVM.ByteCode: Return :: (Maybe LocalType) -> ByteCodeOpr r
+ Language.JVM.ByteCode: Return :: !(Maybe LocalType) -> ByteCodeOpr r
- Language.JVM.ByteCode: Store :: LocalType -> LocalAddress -> ByteCodeOpr r
+ Language.JVM.ByteCode: Store :: !LocalType -> !LocalAddress -> ByteCodeOpr r
- Language.JVM.ByteCode: TableSwitch :: Int32 -> (SwitchTable r) -> ByteCodeOpr r
+ Language.JVM.ByteCode: TableSwitch :: !Int32 -> !(SwitchTable r) -> ByteCodeOpr r
- Language.JVM.ClassFile: ClassAttributes :: [BootstrapMethods r] -> [Signature r] -> [Attribute r] -> ClassAttributes r
+ Language.JVM.ClassFile: ClassAttributes :: [BootstrapMethods r] -> [Signature r] -> [EnclosingMethod r] -> [InnerClasses r] -> [Attribute r] -> ClassAttributes r
- Language.JVM.ClassFileReader: evolveClassFile :: ClassFile Low -> Either ClassFileError (ClassFile High)
+ Language.JVM.ClassFileReader: evolveClassFile :: ((AttributeLocation, Text) -> Bool) -> ClassFile Low -> Either ClassFileError (ClassFile High)
- Language.JVM.ClassFileReader: runEvolve :: ConstantPool High -> Evolve a -> Either ClassFileError a
+ Language.JVM.ClassFileReader: runEvolve :: EvolveConfig -> Evolve a -> Either ClassFileError a

Files

CHANGELOG.md view
@@ -1,5 +1,17 @@ # Change log +## Version 0.2.0++- Add filter to evolveClassFile++## Version 0.1.1++- Add EnclosingMethod Attribute+- Add InnerClasses Attribute+- Add ICAccessFlag +- Add parseing and writing of Signatures+- General optimizations+ ## Version 0.1.0   - Fix documentation
LICENSE.md view
@@ -1,6 +1,6 @@ [The MIT License (MIT)][] -Copyright (c) 2017 Christian Gram Kalhauge+Copyright (c) 2017-2018 Christian Gram Kalhauge  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in
benchmark/Main.hs view
@@ -36,8 +36,10 @@ evolvebm fp =   env (decodeClassFile' fp)$ \clf ->     bgroup ("evolve " ++ fp)-    [ bench "strict"-        (nf evolveClassFile clf)+    [ bench "filter false"+        (nf (evolveClassFile (const False)) clf)+    , bench "filter true"+        (nf (evolveClassFile (const True)) clf)     ]  devolvebm :: FilePath -> Benchmark@@ -62,4 +64,4 @@ ex1 = "test/data/project/Main.class"  ex2 :: String-ex2 = "test/data/java/util/zip/ZipOutputStream.class"+ex2 = "test/data/SQLite.class"
jvm-binary.cabal view
@@ -1,11 +1,11 @@--- This file has been generated from package.yaml by hpack version 0.20.0.+-- This file has been generated from package.yaml by hpack version 0.28.2. -- -- see: https://github.com/sol/hpack ----- hash: 097c125068d4157309ad1e355ed38e1c038f019d7b88ee213afb43df08ad7784+-- hash: 096c3cb1a26134c8a5bb271a50589aea060f4b5891e16c3f03102d2b1fb02660  name:           jvm-binary-version:        0.1.0+version:        0.2.0 synopsis:       A library for reading Java class-files description:    A library for reading Java class-files. category:       Language, Java, JVM@@ -17,7 +17,6 @@ license-file:   LICENSE.md build-type:     Simple cabal-version:  >= 1.10- extra-source-files:     CHANGELOG.md     LICENSE.md@@ -35,7 +34,7 @@   ghc-options: -Wall   build-depends:       attoparsec-    , base >=4.9 && <4.11+    , base >=4.9 && <4.12     , binary     , bytestring     , containers@@ -54,7 +53,9 @@       Language.JVM.Attribute.BootstrapMethods       Language.JVM.Attribute.Code       Language.JVM.Attribute.ConstantValue+      Language.JVM.Attribute.EnclosingMethod       Language.JVM.Attribute.Exceptions+      Language.JVM.Attribute.InnerClasses       Language.JVM.Attribute.LineNumberTable       Language.JVM.Attribute.Signature       Language.JVM.Attribute.StackMapTable@@ -83,7 +84,7 @@   build-depends:       QuickCheck     , attoparsec-    , base >=4.9 && <4.11+    , base >=4.9 && <4.12     , binary     , bytestring     , containers@@ -107,7 +108,9 @@       Language.JVM.Attribute.BootstrapMethodsTest       Language.JVM.Attribute.CodeTest       Language.JVM.Attribute.ConstantValueTest+      Language.JVM.Attribute.EnclosingMethodTest       Language.JVM.Attribute.ExceptionsTest+      Language.JVM.Attribute.InnerClassesTest       Language.JVM.Attribute.LineNumberTableTest       Language.JVM.Attribute.SignatureTest       Language.JVM.Attribute.StackMapTableTest@@ -131,7 +134,7 @@   ghc-options: -rtsopts -threaded -funbox-strict-fields -with-rtsopts=-N   build-depends:       attoparsec-    , base >=4.9 && <4.11+    , base >=4.9 && <4.12     , binary     , bytestring     , containers
package.yaml view
@@ -1,5 +1,5 @@ name: jvm-binary-version: '0.1.0'+version: '0.2.0' author: Christian Gram Kalhauge maintainer: Christian Gram Kalhauge <kalhauge@cs.ucla.edu> synopsis: A library for reading Java class-files@@ -19,7 +19,7 @@ - stack.yaml  dependencies:-- base >= 4.9 && < 4.11+- base >= 4.9 && < 4.12 - binary - bytestring - containers
src/Language/JVM/AccessFlag.hs view
@@ -12,6 +12,7 @@   ( MAccessFlag(..), mflags   , FAccessFlag(..), fflags   , CAccessFlag(..), cflags+  , ICAccessFlag(..), icflags   ) where  import           Language.JVM.Utils@@ -84,6 +85,40 @@  instance Enumish CAccessFlag where   inOrder = cflags+++-- | Access flags for the 'Language.JVM.Attribute.InnerClass'+data ICAccessFlag+  = ICPublic+  | ICPrivate+  | ICProtected+  | ICStatic+  | ICFinal+  | ICInterface+  | ICAbstract+  | ICSynthetic+  | ICAnnotation+  | ICEnum+  deriving (Ord, Show, Eq, NFData, Generic)++-- | The 'Enumish' mapping of the 'CAccessFlag'+icflags :: [(Int, ICAccessFlag)]+icflags =+  [ (0, ICPublic)+  , (1, ICPrivate)+  , (2, ICProtected)+  , (3, ICStatic)+  , (4, ICFinal)+  , (9, ICInterface)+  , (10, ICAbstract)+  , (12, ICSynthetic)+  , (13, ICAnnotation)+  , (14, ICEnum)+  ]++instance Enumish ICAccessFlag where+  inOrder = icflags+  -- | Access flags for the 'Language.JVM.Field.Field' data FAccessFlag
src/Language/JVM/Attribute/Base.hs view
@@ -144,16 +144,23 @@ -- monoid given an 'Attribute' calculate the monoid over all attributes. fromAttributes ::   (Foldable f, EvolveM m, Monoid a)-  => (Attribute High -> m a)+  => AttributeLocation+  -> (Attribute High -> m a)   -> f (Attribute Low)   -> m a-fromAttributes f attrs =-  Prelude.foldl g (return mempty) attrs+fromAttributes al f attrs = do+  afilter <- attributeFilter+  Prelude.foldl (g afilter) (return mempty) attrs   where-    g m a' = do+    g afilter m a' = do       b <- m-      x <- f =<< evolve a'-      return $ b `mappend` x+      ah <- evolve a'+      if afilter (al, aName ah)+        then do+          x <- f ah+          return $ b `mappend` x+      else do+        return b  readFromStrict :: Binary a => Attribute r -> Either String a readFromStrict =
src/Language/JVM/Attribute/Code.hs view
@@ -86,7 +86,7 @@     (offsets, codeByteCode) <- evolveByteCode codeByteCode     let evolver = (evolveOffset offsets)     codeExceptionTable <- mapM (evolveBC evolver) codeExceptionTable-    codeAttributes <- fromCollector <$> fromAttributes (collect' evolver) codeAttributes+    codeAttributes <- fromCollector <$> fromAttributes CodeAttribute (collect' evolver) codeAttributes     return $ Code {..}     where       fromCollector (a, b, c) =
+ src/Language/JVM/Attribute/EnclosingMethod.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE DeriveAnyClass     #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell    #-}+{-|+Module      : Language.JVM.Attribute.EnclosingMethod+Copyright   : (c) Christian Gram Kalhauge, 2018+License     : MIT+Maintainer  : kalhuage@cs.ucla.edu++Based on the EnclosingMethod Attribute,+as documented [here](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.7).+-}++module Language.JVM.Attribute.EnclosingMethod+  ( EnclosingMethod (..)+  ) where++import           Language.JVM.Attribute.Base+import           Language.JVM.Constant+import           Language.JVM.Staged++-- | 'EnclosingMethod' is an Attribute.+instance IsAttribute (EnclosingMethod Low) where+  attrName = Const "EnclosingMethod"++-- | The 'EnclosingMethod' is a reference to the enclosing method of the class+data EnclosingMethod r = EnclosingMethod+  { enclosingClassName :: !(Ref ClassName r)+  , enclosingMethodName :: !(Ref (Maybe MethodId) r)+  }+++instance Staged EnclosingMethod where+  evolve (EnclosingMethod cn mn) = label "EnclosingMethod" $ do+    EnclosingMethod+      <$> link cn+      <*> if mn == 0 then return Nothing else Just <$> link mn++  devolve (EnclosingMethod cn mn) = label "EnclosingMethod" $ do+    EnclosingMethod+      <$> unlink cn+      <*> case mn of+            Nothing -> return 0+            Just mn' -> unlink mn'++$(deriveBaseWithBinary ''EnclosingMethod)
+ src/Language/JVM/Attribute/InnerClasses.hs view
@@ -0,0 +1,71 @@+{-# 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)
src/Language/JVM/Attribute/Signature.hs view
@@ -19,17 +19,57 @@   ( Signature (..)   , signatureToText   , signatureFromText++  -- * Top Level Definitions++  , ClassSignature (..)+  , classSignatureToText+  , classSignatureFromText+  , classSignatureP+  , MethodSignature (..)+  , methodSignatureToText+  , methodSignatureFromText+  , methodSignatureP+  , FieldSignature (..)+  , fieldSignatureToText+  , fieldSignatureFromText+  , fieldSignatureP++  -- * Lower Level Definitions+  , ClassType (..)+  , classTypeP+  , ReferenceType (..)+  , referenceTypeP+  , ThrowsSignature (..)+  , TypeArgument (..)+  , TypeParameter (..)+  , TypeSignature (..)+  , TypeVariable (..)+  , typeVariableP+  , Wildcard (..)+  , typeParameterP+  , typeParametersP   ) where --- import           Control.DeepSeq             (NFData)+import           Control.DeepSeq             (NFData) -- import           Data.Binary -- import qualified Data.IntMap                 as IM import qualified Data.Text                   as Text--- import           GHC.Generics                (Generic)+-- import Data.Monoid++import Data.Text.Lazy.Builder as Text+import qualified Data.Text.Lazy as LText++import Data.Functor+import           GHC.Generics                (Generic) import           Language.JVM.Attribute.Base import           Language.JVM.Staged--- import           Language.JVM.Type+import           Language.JVM.Type +import qualified Data.List                   as L++import           Data.Attoparsec.Text+ instance IsAttribute (Signature Low) where   attrName = Const "Signature" @@ -42,50 +82,283 @@ signatureFromText :: Text.Text -> Signature High signatureFromText s = Signature s --- data ClassSignature = ClassSignature---   { csTypeParameters :: [TypeParameter]---   , csSuperclassSignature :: ClassTypeSignature---   , csInterfaceSignatures :: [ClassTypeSignature]---   } --- data TypeParameter =---   TypeParameter---   { tpIndentifier :: Text.Text---   , tpClassBound :: Maybe ClassName---   , tpInterfaceBound :: [ClassName]---   }+----------------------+-- Parsing+---------------------- --- data ClassTypeSignature---   = ClassTypeSignature---     { ctsClassName :: ClassName---     , ctsTypeArguments :: [TypeArgument]---     }---   | InnerClassTypeSignature---     { ctsInnerClassName :: Text.Text---     , ctsTypeArguments :: [TypeArgument]---     }+data ClassSignature = ClassSignature+  { csTypeParameters      :: [TypeParameter]+  , csSuperclassSignature :: ClassType+  , csInterfaceSignatures :: [ClassType]+  }+  deriving (Show, Eq, Generic, NFData) --- data TypeArgument---   = AnyTypeArgument---   | TypeArgument---     { taWildcard :: Maybe Wildcard---     , taType :: ReferenceType---     }+classSignatureP :: Parser ClassSignature+classSignatureP = do+  tp <- option [] typeParametersP+  ss <- classTypeP+  is <- many' classTypeP+  return $ ClassSignature tp ss is --- data ReferenceType---   = RTClassType ClassTypeSignature---   | RTTypeVariable TypeVariableSignature---   | RTArrayType JavaTypeSignature+classSignatureToText :: ClassSignature -> Text.Text+classSignatureToText =+  LText.toStrict . toLazyText . classSignatureT --- newtype TypeVariableSignature---   = TypeVariableSignature Text.Text+classSignatureFromText :: Text.Text -> Either String ClassSignature+classSignatureFromText =+  parseOnly classSignatureP --- data JavaTypeSignature---   = ReferenceType ReferenceType---   | BaseType JBaseType+classSignatureT :: ClassSignature -> Builder+classSignatureT (ClassSignature tp ct its)= do+  typeParametersT tp <> foldMap classTypeT (ct:its) --- data Wildcard =---   WPlus | WMinus+data TypeSignature+  = ReferenceType ReferenceType+  | BaseType JBaseType+  deriving (Show, Eq, Generic, NFData)++typeSignatureP :: Parser TypeSignature+typeSignatureP = do+  choice [ (ReferenceType <$> referenceTypeP) <?> "JRefereceType"+         , (BaseType <$> jBaseTypeP) <?> "JBaseType" ]++typeSignatureT :: TypeSignature -> Builder+typeSignatureT (ReferenceType t) = referenceTypeT t+typeSignatureT (BaseType t) = singleton (jBaseTypeToChar t)++data ReferenceType+  = RefClassType ClassType+  | RefTypeVariable TypeVariable+  | RefArrayType TypeSignature+  deriving (Show, Eq, Generic, NFData)++referenceTypeP :: Parser ReferenceType+referenceTypeP = do+  choice+    [ RefClassType <$> classTypeP+    , RefTypeVariable <$> typeVariableP+    , RefArrayType <$> (char '[' >> typeSignatureP)+    ]++referenceTypeT :: ReferenceType -> Builder+referenceTypeT t =+  case t of+    RefClassType ct -> classTypeT ct+    RefTypeVariable tv -> typeVariableT tv+    RefArrayType at -> singleton '[' <> typeSignatureT at++data ClassType+  = ClassType+    { ctsClassName     :: ClassName+    , ctsTypeArguments :: [Maybe TypeArgument]+    }+  | InnerClassType+    { ctsInnerClassName :: Text.Text+    , ctsOuterClassType :: ClassType+    , ctsTypeArguments  :: [Maybe TypeArgument]+    }+  deriving (Show, Eq, Generic, NFData)++classTypeP :: Parser ClassType+classTypeP = nameit "ClassType" $ do+  _ <- char 'L'+  cn <- (ClassName <$> takeWhile1 (notInClass ".;[<>:")) <?> "ClassName"+  ta <- option [] typeArgumentsP+  ict <- many' $ do+      _ <- char '.'+      i <- identifierP+      ta' <- option [] typeArgumentsP+      return (i, ta')+  _ <- char ';'+  return $ L.foldl' (\a (i,ta') -> InnerClassType i a ta') (ClassType cn ta) ict++classTypeT :: ClassType -> Builder+classTypeT t =+  go t <> singleton ';'+  where+    go t' =+      case t' of+        InnerClassType n ct arg ->+          go ct <> singleton '.' <> Text.fromText n <> typeArgumentsT arg+        ClassType cn arg ->+          singleton 'L'+          <> Text.fromText (classNameAsText cn)+          <> typeArgumentsT arg++data TypeArgument = TypeArgument+  { taWildcard :: Maybe Wildcard+  , taType     :: ReferenceType+  }+  deriving (Show, Eq, Generic, NFData)++typeArgumentsP :: Parser [ Maybe TypeArgument ]+typeArgumentsP = do+  _ <- char '<'+  tas <- many1' typeArgumentP+  _ <- char '>'+  return tas++typeArgumentP :: Parser (Maybe TypeArgument)+typeArgumentP = do+  choice [ Just+           <$> ( TypeArgument+                  <$> option Nothing (Just <$> wildcardP)+                  <*> referenceTypeP+               )+         , char '*' $> Nothing+         ] <?> "TypeArgument"++typeArgumentsT :: [ Maybe TypeArgument ] -> Builder+typeArgumentsT args = do+  if L.null args+    then mempty+    else singleton '<' <> foldMap typeArgumentT args <> singleton '>'++typeArgumentT :: Maybe TypeArgument -> Builder+typeArgumentT a = do+  case a of+    Nothing -> singleton '*'+    Just (TypeArgument w rt) ->+      (case w of+        Just WildMinus -> singleton '-'+        Just WildPlus -> singleton '+'+        Nothing -> mempty) <> referenceTypeT rt++data Wildcard =+  WildPlus | WildMinus+  deriving (Show, Eq, Generic, NFData)++wildcardP :: Parser Wildcard+wildcardP = choice [ char '+' $> WildPlus, char '-' $> WildMinus]++newtype TypeVariable =+  TypeVariable { tvAsText :: Text.Text }+  deriving (Show, Eq, Generic, NFData)++typeVariableP :: Parser TypeVariable+typeVariableP = do+  _ <- char 'T'+  t <- identifierP+  _ <- char ';'+  return $ TypeVariable t++typeVariableT :: TypeVariable -> Builder+typeVariableT (TypeVariable t)= do+  singleton 'T' <> Text.fromText t <> singleton ';'++data TypeParameter =+  TypeParameter+  { tpIndentifier    :: Text.Text+  , tpClassBound     :: Maybe ReferenceType+  , tpInterfaceBound :: [ReferenceType]+  }+  deriving (Show, Eq, Generic, NFData)++typeParametersP :: Parser [TypeParameter]+typeParametersP = nameit "TypeParameters" $ do+  _ <- char '<'+  tps <- many1' typeParameterP+  _ <- char '>'+  return tps++typeParametersT :: [ TypeParameter ] -> Builder+typeParametersT args = do+  if L.null args+    then mempty+    else singleton '<' <> foldMap typeParameterT args <> singleton '>'++typeParameterP :: Parser TypeParameter+typeParameterP = nameit "TypeParameter" $ do+  id_ <- identifierP+  _ <- char ':'+  cb <- option Nothing (Just <$> referenceTypeP)+  ib <- many' (char ':' >> referenceTypeP)+  return $ TypeParameter id_ cb ib++typeParameterT :: TypeParameter -> Builder+typeParameterT (TypeParameter n cb ibs) =+  Text.fromText  n <> singleton ':' <> maybe mempty referenceTypeT cb <>+    foldMap (\i -> singleton ':' <> referenceTypeT i) ibs++nameit :: String -> Parser a -> Parser a+nameit str m = m <?> str++identifierP :: Parser Text.Text+identifierP =+  takeWhile1 (notInClass ".;[/<>:") <?> "Identifier"+++data MethodSignature = MethodSignature+  { msTypeParameters :: [TypeParameter]+  , msArguments      :: [TypeSignature]+  , msResults        :: Maybe TypeSignature+  , msThrows         :: [ ThrowsSignature ]+  }+  deriving (Show, Eq, Generic, NFData)++methodSignatureP :: Parser MethodSignature+methodSignatureP = do+  tps <- option [] typeParametersP+  _ <- char '('+  targ <- many' typeSignatureP+  _ <- char ')'+  res <- choice [ Just <$> typeSignatureP, char 'V' $> Nothing ]+  thrws <- many' throwsSignatureP+  return $ MethodSignature tps targ res thrws++methodSignatureToText :: MethodSignature -> Text.Text+methodSignatureToText =+  LText.toStrict . toLazyText . methodSignatureT++methodSignatureFromText :: Text.Text -> Either String MethodSignature+methodSignatureFromText =+  parseOnly methodSignatureP++fieldSignatureFromText :: Text.Text -> Either String FieldSignature+fieldSignatureFromText =+  parseOnly fieldSignatureP++methodSignatureT :: MethodSignature -> Builder+methodSignatureT (MethodSignature tp args res thrws)= do+  typeParametersT tp+    <> singleton '('+    <> foldMap typeSignatureT args+    <> singleton ')'+    <> (case res of Nothing -> singleton 'V'; Just r -> typeSignatureT r)+    <> foldMap throwsSignatureT thrws++data ThrowsSignature+  = ThrowsClass ClassType+  | ThrowsTypeVariable TypeVariable+  deriving (Show, Eq, Generic, NFData)++throwsSignatureP :: Parser ThrowsSignature+throwsSignatureP = do+  _ <- char '^'+  choice [ ThrowsClass <$> classTypeP, ThrowsTypeVariable <$> typeVariableP]+++throwsSignatureT :: ThrowsSignature -> Builder+throwsSignatureT t =+  singleton '^'+    <> case t of+         ThrowsClass ct -> classTypeT ct+         ThrowsTypeVariable tt -> typeVariableT tt++++newtype FieldSignature =+  FieldSignature {fsRefType :: ReferenceType}+  deriving (Show, Eq, Generic, NFData)++fieldSignatureP :: Parser FieldSignature+fieldSignatureP =+  FieldSignature <$> referenceTypeP++fieldSignatureToText :: FieldSignature -> Text.Text+fieldSignatureToText =+  LText.toStrict . toLazyText . referenceTypeT . fsRefType  instance Staged Signature where   evolve (Signature a) =
src/Language/JVM/ByteCode.hs view
@@ -1,4 +1,5 @@ {-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# OPTIONS_GHC -funbox-strict-fields #-} {-# LANGUAGE DeriveAnyClass     #-} {-# LANGUAGE DeriveGeneric      #-} {-# LANGUAGE FlexibleContexts   #-}@@ -81,7 +82,7 @@ import           Data.Binary.Put       hiding (Put) import qualified Data.ByteString.Lazy  as BL import           Data.Int-import qualified Data.IntMap           as IM+import qualified Data.IntMap.Strict           as IM import qualified Data.Vector           as V  import           Language.JVM.Constant@@ -179,8 +180,9 @@  evolveByteCode :: EvolveM m => ByteCode Low -> m (OffsetMap, ByteCode High) evolveByteCode bc@(ByteCode (_, v)) = do-  let om = offsetMap bc-  (om,) . ByteCode <$> V.mapM (fmap opcode . evolveByteCodeInst (evolveOffset om)) v+  let !om = offsetMap bc+  x <- V.mapM (fmap opcode . evolveByteCodeInst (evolveOffset om)) v+  return . (om,) . ByteCode $! x  devolveByteCode :: DevolveM m => ByteCode High -> m (ByteCode Low) devolveByteCode (ByteCode bc) = do@@ -239,11 +241,14 @@     TableSwitch i (SwitchTable l ofss) ->       label "TableSwitch" $ (TableSwitch i . SwitchTable l <$> V.mapM calcOffset ofss)     a                 -> return $ unsafeCoerce a-  return (ByteCodeInst ofs x)+  return $ seq x (ByteCodeInst ofs x)   where     calcOffset r =       g (fromIntegral $ fromIntegral ofs + r) +{-# INLINABLE evolveByteCodeInst #-}++ devolveByteCodeInst ::   DevolveM m   => (ByteCodeIndex -> m ByteCodeOffset)@@ -322,8 +327,10 @@     putLazyByteString bs  instance Binary (ByteCodeInst Low) where-  get =-    ByteCodeInst <$> (fromIntegral <$> bytesRead) <*> get+  get = do+    i <- (fromIntegral <$> bytesRead)+    x <- get+    return $! ByteCodeInst i x   put x =     putByteCode (offset x) $ opcode x @@ -350,17 +357,17 @@  data ExactArrayType r   = EABoolean | EAByte | EAChar | EAShort | EAInt | EALong-  | EAFloat | EADouble | EARef (Ref ClassName r)+  | EAFloat | EADouble | EARef !(Ref ClassName r)  data Invocation r-  = InvkSpecial (DeepRef AbsVariableMethodId r)+  = InvkSpecial !(DeepRef AbsVariableMethodId r)   -- ^ Variable since 52.0-  | InvkVirtual (DeepRef AbsMethodId r)-  | InvkStatic (DeepRef AbsVariableMethodId r)+  | InvkVirtual !(DeepRef AbsMethodId r)+  | InvkStatic !(DeepRef AbsVariableMethodId r)   -- ^ Variable since 52.0-  | InvkInterface Word8 (DeepRef AbsInterfaceMethodId r)+  | InvkInterface !Word8 !(DeepRef AbsInterfaceMethodId r)   -- ^ Should be a positive number-  | InvkDynamic (DeepRef InvokeDynamic r)+  | InvkDynamic !(DeepRef InvokeDynamic r)  data FieldAccess   = FldStatic@@ -372,7 +379,6 @@  type WordSize = OneOrTwo - evolveBConstant :: EvolveM m => BConstant Low -> m (BConstant High) evolveBConstant ccnst = do   x <- evolve ccnst@@ -511,80 +517,80 @@     len = fromIntegral . V.length $ switchOffsets st  data ByteCodeOpr r-  = ArrayLoad ArrayType+  = ArrayLoad !ArrayType   -- ^ aaload baload ...-  | ArrayStore ArrayType+  | ArrayStore !ArrayType   -- ^ aastore bastore ... -  | Push (BConstant r)+  | Push !(BConstant r) -  | Load LocalType LocalAddress+  | Load !LocalType !LocalAddress   -- ^ aload_0, bload_2, iload 5 ...-  | Store LocalType LocalAddress+  | Store !LocalType !LocalAddress   -- ^ aload, bload ... -  | BinaryOpr BinOpr ArithmeticType+  | BinaryOpr !BinOpr !ArithmeticType   -- ^ iadd ...-  | Neg ArithmeticType+  | Neg !ArithmeticType   -- ^ ineg ... -  | BitOpr BitOpr WordSize+  | BitOpr !BitOpr !WordSize   -- ^ Exclusively on int and long, identified by the word-size    | IncrLocal !LocalAddress !IncrementAmount   -- ^ Only works on ints, increment local #1, with #2 -  | Cast CastOpr+  | Cast !CastOpr   -- ^ Only valid on different types    | CompareLongs -  | CompareFloating Bool WordSize+  | CompareFloating !Bool !WordSize   -- ^ Compare two floating values, #1 indicates if greater-than, #2   -- is if float or double should be used. -  | If CmpOpr OneOrTwo (ShortRelativeRef r)+  | If !CmpOpr !OneOrTwo !(ShortRelativeRef r)   -- ^ compare with 0 if #2 is False, and two ints from the stack if   -- True. the last value is the offset -  | IfRef Bool OneOrTwo (ShortRelativeRef r)+  | IfRef !Bool !OneOrTwo !(ShortRelativeRef r)   -- ^ check if two objects are equal, or not equal. If #2 is True, compare   -- with null. -  | Goto (LongRelativeRef r)-  | Jsr (LongRelativeRef r)-  | Ret LocalAddress+  | Goto !(LongRelativeRef r)+  | Jsr !(LongRelativeRef r)+  | Ret !LocalAddress -  | TableSwitch Int32 (SwitchTable r)+  | TableSwitch !Int32 !(SwitchTable r)   -- ^ a table switch has 2 values a `default` and a `SwitchTable`-  | LookupSwitch Int32 (V.Vector (Int32, Int32))+  | LookupSwitch !Int32 (V.Vector (Int32, Int32))   -- ^ a lookup switch has a `default` value and a list of pairs. -  | Get FieldAccess (DeepRef (InClass FieldId) r)-  | Put FieldAccess (DeepRef (InClass FieldId) r)+  | Get !FieldAccess !(DeepRef (InClass FieldId) r)+  | Put !FieldAccess !(DeepRef (InClass FieldId) r) -  | Invoke (Invocation r)+  | Invoke !(Invocation r) -  | New (Ref ClassName r)+  | New !(Ref ClassName r) -  | NewArray (ExactArrayType r)+  | NewArray !(ExactArrayType r)    | ArrayLength    | Throw -  | CheckCast (Ref ClassName r)-  | InstanceOf (Ref ClassName r)+  | CheckCast !(Ref ClassName r)+  | InstanceOf !(Ref ClassName r) -  | Monitor Bool+  | Monitor !Bool   -- ^ True => Enter, False => Exit    -- TODO: Fix this so that its more clear what it points to.-  | MultiNewArray (Ref ClassName r) Word8+  | MultiNewArray !(Ref ClassName r) !Word8   -- ^ Create a new multi array of #1 and with #2 dimensions   -- ^ This might point to an array type. -  | Return (Maybe LocalType)+  | Return !(Maybe LocalType)    | Nop @@ -926,6 +932,8 @@       0xc9 -> Jsr <$> getInt32be        _ -> fail $ "I do not know this bytecode '0x" ++ showHex cmd "'."++  {-# INLINABLE get#-}    put = putByteCode 0 
src/Language/JVM/ClassFile.hs view
@@ -18,6 +18,8 @@   , cFields   , cMethods   , cSignature+  , cEnclosingMethod+  , cInnerClasses    -- * Attributes   , ClassAttributes (..)@@ -31,6 +33,8 @@ import           Language.JVM.AccessFlag import           Language.JVM.Attribute import           Language.JVM.Attribute.BootstrapMethods+import           Language.JVM.Attribute.EnclosingMethod+import           Language.JVM.Attribute.InnerClasses -- import           Language.JVM.Attribute.Signature import           Language.JVM.Constant import           Language.JVM.ConstantPool               as CP@@ -89,9 +93,23 @@ cSignature =   firstOne . caSignature . cAttributes +cEnclosingMethod :: ClassFile High -> Maybe (EnclosingMethod High)+cEnclosingMethod =+  firstOne . caEnclosingMethod . cAttributes++cInnerClasses' :: ClassFile High -> Maybe (InnerClasses High)+cInnerClasses' =+  firstOne . caInnerClasses . cAttributes++cInnerClasses :: ClassFile High -> [InnerClass High]+cInnerClasses =+  maybe [] innerClasses . cInnerClasses'+ data ClassAttributes r = ClassAttributes   { caBootstrapMethods :: [ BootstrapMethods r]   , caSignature        :: [ Signature r ]+  , caEnclosingMethod  :: [ EnclosingMethod r ]+  , caInnerClasses     :: [ InnerClasses r ]   , caOthers           :: [ Attribute r ]   } @@ -107,7 +125,7 @@     cii' <- mapM link $ cInterfaces cf     cf' <- mapM evolve $ cFields' cf     cm' <- mapM evolve $ cMethods' cf-    ca' <- fromCollector <$> fromAttributes collect' (cAttributes cf)+    ca' <- fromCollector <$> fromAttributes ClassAttribute collect' (cAttributes cf)     return $ cf       { cConstantPool = ()       , cThisClass = tci'@@ -118,12 +136,14 @@       , cAttributes         = ca'       }     where-      fromCollector (a, b, c) =-        ClassAttributes (appEndo a []) (appEndo b []) (appEndo c [])+      fromCollector = flip appEndo (ClassAttributes [] [] [] [] [])       collect' attr =-        collect (mempty, mempty, Endo (attr:)) attr-          [ toC $ \e -> (Endo (e:), mempty, mempty)-          , toC $ \e -> (mempty, Endo (e:), mempty)]+        collect (Endo (\ca -> ca {caOthers = attr: caOthers ca})) attr+          [ toC $ \e -> Endo (\ca -> ca {caSignature = e : caSignature ca})+          , toC $ \e -> Endo (\ca -> ca {caEnclosingMethod = e : caEnclosingMethod ca})+          , toC $ \e -> Endo (\ca -> ca {caBootstrapMethods = e : caBootstrapMethods ca})+          , toC $ \e -> Endo (\ca -> ca {caInnerClasses = e : caInnerClasses ca})+          ]    devolve cf = do     tci' <- unlink (cThisClass cf)@@ -147,11 +167,14 @@       , cAttributes         = SizedList ca'       }     where-      fromClassAttributes (ClassAttributes cm cs at) = do-        cm' <- mapM toAttribute cm-        cs' <- mapM toAttribute cs-        at' <- mapM devolve at-        return (cm' ++ cs' ++ at')+      fromClassAttributes (ClassAttributes cm cs cem cin at) = do+        concat <$> sequence+          [ mapM toAttribute cm+          , mapM toAttribute cs+          , mapM toAttribute cem+          , mapM toAttribute cin+          , mapM devolve at+          ]  $(deriveBase ''ClassAttributes) $(deriveBaseWithBinary ''ClassFile)
src/Language/JVM/ClassFileReader.hs view
@@ -19,6 +19,7 @@   -- * Evolve   , Evolve   , ClassFileError+  , EvolveConfig (..)   , runEvolve   , bootstrapConstantPool @@ -30,16 +31,18 @@   , cpbEmpty   ) where -import           Control.DeepSeq           (NFData)+import           Control.DeepSeq (NFData) import           Control.Monad.Except import           Control.Monad.Reader import           Control.Monad.State-import qualified Data.ByteString.Lazy      as BL-import qualified Data.IntMap               as IM-import qualified Data.Map                  as Map-import           Data.Monoid import           Data.Binary-import           GHC.Generics              (Generic)+import qualified Data.ByteString.Lazy as BL+import qualified Data.IntMap as IM+import qualified Data.Map as Map+import qualified Data.List as List+import qualified Data.Text as Text+import           Data.Monoid+import           GHC.Generics (Generic)  import           Language.JVM.ClassFile import           Language.JVM.Constant@@ -66,11 +69,16 @@ encodeClassFile clf = do   encode clf --- | Changed the stage from Index to Deref-evolveClassFile :: ClassFile Low -> Either ClassFileError (ClassFile High)-evolveClassFile cf = do+-- | Evolve the class file to inline the references. A filter function is+-- provided to remove some attributes. This will sometimes give faster loading+-- times.+evolveClassFile ::+  ((AttributeLocation, Text.Text) -> Bool)+  -> ClassFile Low+  -> Either ClassFileError (ClassFile High)+evolveClassFile fn cf = do   cp <- bootstrapConstantPool (cConstantPool cf)-  runEvolve cp (evolve cf)+  runEvolve (EvolveConfig [] cp fn ) (evolve cf)  -- | Devolve a ClassFile from High to Low. This might make the 'ClassFile' contain -- invalid attributes, since we can't read all attributes. If this this is a problem@@ -89,12 +97,11 @@   let (cf', cpb) = runConstantPoolBuilder (devolve cf) (builderFromConstantPool cp) in   cf' { cConstantPool = cpbConstantPool cpb } - -- | Top level command that combines 'decode' and 'evolve'. readClassFile :: BL.ByteString -> Either ClassFileError (ClassFile High) readClassFile bs = do   clf <- decodeClassFile bs-  evolveClassFile clf+  evolveClassFile (const True) clf  -- | Top level command that combines 'devolve' and 'encode'. writeClassFile :: ClassFile High -> BL.ByteString@@ -123,31 +130,45 @@  instance NFData ClassFileError +data EvolveConfig =+  EvolveConfig+  { ecLabel :: [String]+  , ecConstantPool :: ConstantPool High+  , ecAttributeFilter :: ((AttributeLocation, Text.Text) -> Bool)+  }+ newtype Evolve a =-  Evolve (ReaderT (String, ConstantPool High) (Either ClassFileError) a)+  Evolve (ReaderT EvolveConfig (Either ClassFileError) a)   deriving   ( Functor   , Applicative   , Monad-  , MonadReader (String, ConstantPool High)+  , MonadReader EvolveConfig   , MonadError ClassFileError   ) -runEvolve :: ConstantPool High -> Evolve a -> Either ClassFileError a-runEvolve cp (Evolve m) = runReaderT m ("", cp)+runEvolve :: EvolveConfig -> Evolve a -> Either ClassFileError a+runEvolve ev (Evolve m) = runReaderT m ev  instance LabelM Evolve where   label str (Evolve m) = do-    Evolve . withReaderT (\(x, cp) -> (x ++ "/" ++ str, cp)) $ m+    Evolve . withReaderT (\ec -> ec { ecLabel = str : ecLabel ec}) $ m +showLvl :: [String] -> String+showLvl = List.intercalate "/" . reverse+ instance EvolveM Evolve where   link w = do-    (lvl, cp) <- ask-    r <- either (throwError . CFEPoolAccessError lvl ) return $ access w cp+    ec <- ask+    let lvl = showLvl ( ecLabel ec )+    r <- either (throwError . CFEPoolAccessError lvl)  return $ access w (ecConstantPool ec)     fromConst (throwError . CFEInconsistentClassPool lvl) r +  attributeFilter =+    asks ecAttributeFilter+   attributeError msg = do-    (lvl, _) <- ask+    lvl <- asks (showLvl . ecLabel)     throwError (CFEConversionError lvl msg)  -- | Untie the constant pool, this requires a special operation as the constant pool@@ -162,20 +183,24 @@            $ "Could not load all constants in the constant pool: " ++ (show xs)   where     stage' cp mis =-      let (cp', mis') = foldMap (grow cp) mis in-      case appEndo mis' [] of-        [] | IM.null cp' -> Right cp-        xs-          | IM.null cp' ->-            Left xs-          | otherwise ->-            stage' (cp `IM.union` cp') (map snd xs)+      let (cp', mis') =+            foldMap (grow (EvolveConfig [] (ConstantPool cp) (const True))) mis+      in if IM.null cp'+        then+          case appEndo mis' [] of+            [] -> Right cp+            xs -> Left xs+        else+          stage' (cp `IM.union` cp') . map snd $ appEndo mis' [] -    grow cp (k,a) =-      case runEvolve (ConstantPool cp) $ evolve a of+    grow :: EvolveConfig -> (Int, Constant Low) -> (IM.IntMap (Constant High), Endo [(ClassFileError, (Int, Constant Low))])+    grow ec (k,a) =+      case runEvolve ec (evolve a) of         Right c -> (IM.singleton k c, Endo id)         Left msg  -> (IM.empty, Endo ((msg, (k,a)):)) +{-# SCC bootstrapConstantPool #-}+ -- $build  data CPBuilder = CPBuilder@@ -198,7 +223,7 @@   deriving (Monad, MonadState CPBuilder, Functor, Applicative)  runConstantPoolBuilder :: ConstantPoolBuilder a -> CPBuilder -> (a, CPBuilder)-runConstantPoolBuilder (ConstantPoolBuilder m) a=+runConstantPoolBuilder (ConstantPoolBuilder m) a =   runState m a  instance LabelM ConstantPoolBuilder
src/Language/JVM/ConstantPool.hs view
@@ -91,6 +91,7 @@     Just x -> Right x     Nothing -> Left $ PoolAccessError ref "No such element." + -- | Append a constant to the constant pool, and get the offset. append :: Constant r -> ConstantPool r -> (Index, ConstantPool r) append c (ConstantPool cp) =
src/Language/JVM/Field.hs view
@@ -64,7 +64,7 @@   evolve field = label "Field" $ do     fi <- link (fName field)     fd <- link (fDescriptor field)-    fattr <- fromCollector <$> fromAttributes collect' (fAttributes field)+    fattr <- fromCollector <$> fromAttributes FieldAttribute collect' (fAttributes field)     return $ Field (fAccessFlags' field) fi fd fattr     where       fromCollector (cv, sig, others) =
src/Language/JVM/Method.hs view
@@ -85,7 +85,7 @@     mn' <- link mn     md' <- link md     mattr' <- label (Text.unpack (mn' <> ":" <> toText md'))-      $ fromCollector <$> fromAttributes collect' mattr+      $ fromCollector <$> fromAttributes MethodAttribute collect' mattr     return $ Method mf mn' md' mattr'     where       fromCollector (a, b, c, d) =
src/Language/JVM/Staged.hs view
@@ -15,11 +15,17 @@   , LabelM (..)   , EvolveM (..)   , DevolveM (..)++  -- * AttributeLocation+  , AttributeLocation (..)+   -- * Re-exports   , module Language.JVM.Stage   , module Language.JVM.TH   ) where +import qualified Data.Text as Text+ import Language.JVM.Constant import Language.JVM.Stage import Language.JVM.TH@@ -29,8 +35,16 @@   -- ^ label the current position in the class-file, good for debugging   label _ = id +data AttributeLocation+  = ClassAttribute+  | MethodAttribute+  | CodeAttribute+  | FieldAttribute+  deriving (Show, Eq, Ord)+ class LabelM m => EvolveM m where   link :: Referenceable r => Index -> m r+  attributeFilter :: m ((AttributeLocation, Text.Text) -> Bool)   attributeError :: String -> m r  class LabelM m => DevolveM m where
src/Language/JVM/Type.hs view
@@ -21,6 +21,8 @@   -- ** JType   , JType (..)   , JBaseType (..)+  , jBaseTypeP+  , jBaseTypeToChar    -- ** MethodDescriptor   , MethodDescriptor (..)@@ -100,46 +102,55 @@  class TypeParse a where   fromText :: Text.Text -> Either String a-  fromText = parseOnly parseText+  fromText = parseOnly (parseText <* endOfInput)   parseText :: Parser a   toText :: a -> Text.Text +jBaseTypeP :: Parser JBaseType+jBaseTypeP = do+  s <- satisfy (inClass "BCDFIJSZ") <?> "BaseType"+  case s of+    'B' -> return $ JTByte+    'C' -> return $ JTChar+    'D' -> return $ JTDouble+    'F' -> return $ JTFloat+    'I' -> return $ JTInt+    'J' -> return $ JTLong+    'S' -> return $ JTShort+    'Z' -> return $ JTBoolean+    _ -> error "should not happen"++jBaseTypeToChar :: JBaseType -> Char+jBaseTypeToChar y = do+  case y of+    JTByte    -> 'B'+    JTChar    -> 'C'+    JTDouble  -> 'D'+    JTFloat   -> 'F'+    JTInt     -> 'I'+    JTLong    -> 'J'+    JTShort   -> 'S'+    JTBoolean -> 'Z'+ instance TypeParse JType where-  parseText = try $ do-    s <- anyChar-    case s :: Char of-      'B' -> return $ JTBase JTByte-      'C' -> return $ JTBase JTChar-      'D' -> return $ JTBase JTDouble-      'F' -> return $ JTBase JTFloat-      'I' -> return $ JTBase JTInt-      'J' -> return $ JTBase JTLong-      'L' -> do-        txt <- takeWhile (/= ';')-        _ <- char ';'-        return $ JTClass (ClassName txt)-      'S' -> return $ JTBase JTShort-      'Z' -> return $ JTBase JTBoolean-      '[' -> JTArray <$> parseText-      _ -> fail $ "Unknown char " ++ show s+  parseText = do+    choice+      [ JTBase <$> jBaseTypeP+      , do+          _ <- char 'L'+          txt <- takeWhile (/= ';')+          _ <- char ';'+          return $ JTClass (ClassName txt)+      , char '[' >> JTArray <$> parseText+      ]   toText tp =     Text.pack $ go tp ""     where       go x =         case x of-          JTBase y               -> textbase y+          JTBase y               -> (jBaseTypeToChar y :)           JTClass (ClassName cn) -> ((('L':Text.unpack cn) ++ ";") ++)           JTArray tp'            -> ('[':) . go tp'-      textbase y =-        case y of-          JTByte    -> ('B':)-          JTChar    -> ('C':)-          JTDouble  -> ('D':)-          JTFloat   -> ('F':)-          JTInt     -> ('I':)-          JTLong    -> ('J':)-          JTShort   -> ('S':)-          JTBoolean -> ('Z':)  instance TypeParse MethodDescriptor where   toText md =
stack.yaml view
@@ -1,4 +1,4 @@-resolver: lts-10.5+resolver: lts-12.11 packages: - . flags: {}
+ test/Language/JVM/Attribute/EnclosingMethodTest.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}++module Language.JVM.Attribute.EnclosingMethodTest where++import           SpecHelper++import           Language.JVM.ConstantTest               ()++import           Language.JVM.Attribute.EnclosingMethod+import           Language.JVM++prop_roundtrip_EnclosingMethodTest :: EnclosingMethod High -> Property+prop_roundtrip_EnclosingMethodTest = isoRoundtrip+++spec_enclosing ::  SpecWith ()+spec_enclosing = do+  it "can find an enclosing method in 'Streams$5'" $ do+    tc <- withTestClass "Streams$5"+    cEnclosingMethod tc `shouldBe`+       Just (EnclosingMethod+             "com/google/common/collect/Streams"+             (Just ("mapWithIndex:(Ljava/util/stream/DoubleStream;Lcom/google/common/collect/Streams$DoubleFunctionWithIndex;)Ljava/util/stream/Stream;"))+            )++-- test_real_signatures :: SpecWith ()+-- test_real_signatures = do+--   it "can handle Iterator" $ do+--    let signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;"++instance Arbitrary (EnclosingMethod High) where+  arbitrary = genericArbitraryU+++  -- "Lcom/apple/eawt/_AppEventHandler$_AppEventDispatcher<Lcom/apple/eawt/QuitHandler;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/ScreenSleepListener;Lcom/apple/eawt/AppEvent$ScreenSleepEvent;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/SystemSleepListener;Lcom/apple/eawt/AppEvent$SystemSleepEvent;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/UserSessionListener;Lcom/apple/eawt/AppEvent$UserSessionEvent;>;"
+ test/Language/JVM/Attribute/InnerClassesTest.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}++module Language.JVM.Attribute.InnerClassesTest where++import           SpecHelper+import qualified Data.Set as S++import           Language.JVM.ConstantTest               ()++import           Language.JVM.Attribute.InnerClasses+import           Language.JVM++prop_roundtrip_InnerClassesTest :: InnerClasses High -> Property+prop_roundtrip_InnerClassesTest = isoRoundtrip++spec_inner_classes ::  SpecWith ()+spec_inner_classes = do+  it "can find the inner classes of 'Streams$5'" $ do+    tc <- withTestClass "Streams$5"+    cInnerClasses tc `shouldBe`+      [+          InnerClass {+              icClassName = "java/util/PrimitiveIterator$OfDouble",+              icOuterClassName = Just "java/util/PrimitiveIterator",+              icInnerName = Just "OfDouble",+              icInnerAccessFlags = BitSet $ S.fromList [ICPublic, ICStatic, ICInterface, ICAbstract]+          },+          InnerClass {+              icClassName = "com/google/common/collect/Streams$DoubleFunctionWithIndex",+              icOuterClassName = Just "com/google/common/collect/Streams",+              icInnerName = Just "DoubleFunctionWithIndex",+              icInnerAccessFlags = BitSet $ S.fromList [ICPublic, ICStatic, ICInterface, ICAbstract]+          },+          InnerClass {+              icClassName = "com/google/common/collect/Streams$5",+              icOuterClassName = Nothing,+              icInnerName = Nothing,+              icInnerAccessFlags = BitSet $ S.fromList [ ICStatic ]+          },+          InnerClass {+              icClassName = "java/util/Spliterators$AbstractSpliterator",+              icOuterClassName = Just "java/util/Spliterators",+              icInnerName = Just "AbstractSpliterator",+              icInnerAccessFlags = BitSet $ S.fromList [ICPublic, ICStatic, ICAbstract]+          }+      ]++-- test_real_signatures :: SpecWith ()+-- test_real_signatures = do+--   it "can handle Iterator" $ do+--    let signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;"++instance Arbitrary (InnerClasses High) where+  arbitrary = genericArbitraryU++instance Arbitrary (InnerClass High) where+  arbitrary = genericArbitraryU+++  -- "Lcom/apple/eawt/_AppEventHandler$_AppEventDispatcher<Lcom/apple/eawt/QuitHandler;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/ScreenSleepListener;Lcom/apple/eawt/AppEvent$ScreenSleepEvent;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/SystemSleepListener;Lcom/apple/eawt/AppEvent$SystemSleepEvent;>;"+-- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/UserSessionListener;Lcom/apple/eawt/AppEvent$UserSessionEvent;>;"
test/Language/JVM/Attribute/SignatureTest.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}  module Language.JVM.Attribute.SignatureTest where @@ -9,17 +10,183 @@ import           Language.JVM.Attribute.Signature import           Language.JVM +import qualified Data.Text as Text+import Data.Attoparsec.Text+ prop_roundtrip_SignatureTest :: Signature High -> Property prop_roundtrip_SignatureTest = isoRoundtrip --- test_real_signatures :: SpecWith ()--- test_real_signatures = do---   it "can handle Iterator" $ do---    let signature = "<T:Ljava/lang/Object;>Ljava/lang/Object;"+prop_field_signature :: FieldSignature -> Property+prop_field_signature sig =+  let txt = fieldSignatureToText sig in+    counterexample (Text.unpack txt) $+      fieldSignatureFromText txt === Right sig +prop_method_signature :: MethodSignature -> Property+prop_method_signature sig =+  let txt = methodSignatureToText sig in+    counterexample (Text.unpack txt) $+      methodSignatureFromText txt === Right sig++prop_class_signature :: ClassSignature -> Property+prop_class_signature sig =+  let txt = classSignatureToText sig in+    counterexample (Text.unpack txt) $+      classSignatureFromText txt === Right sig++spec_real_signatures :: SpecWith ()+spec_real_signatures = do+  it "can handle this class type Ljava/lang/Object;" $ do+   let sig = "Ljava/lang/Object;"+   parseOnly referenceTypeP sig `shouldBe`+       Right (RefClassType (ClassType "java/lang/Object" []))++  it "can handle this type parameter E:Ljava/lang/Object;" $ do+   let sig = "E:Ljava/lang/Object;"+   parseOnly typeParameterP sig `shouldBe`+       Right (TypeParameter {+              tpIndentifier = "E",+              tpClassBound = Just (RefClassType (ClassType "java/lang/Object" [])),+              tpInterfaceBound = []+              })+  it "can handle this type parameter <E:Ljava/lang/Object;>" $ do+   let sig = "<E:Ljava/lang/Object;>"+   parseOnly typeParametersP sig `shouldBe`+       Right [+           TypeParameter {+               tpIndentifier = "E",+               tpClassBound = Just (RefClassType (ClassType {+                   ctsClassName = "java/lang/Object",+                   ctsTypeArguments = []+               })),+               tpInterfaceBound = []+           }+       ]+  it "can handle the class signature of Iterator" $ do+   let sig = "<E:Ljava/lang/Object;>Ljava/lang/Object;"+   parseOnly classSignatureP sig `shouldBe`+       Right (ClassSignature {+           csTypeParameters = [+               TypeParameter {+                   tpIndentifier = "E",+                   tpClassBound = Just (RefClassType (ClassType {+                       ctsClassName = "java/lang/Object",+                       ctsTypeArguments = []+                   })),+                   tpInterfaceBound = []+               }+           ],+           csSuperclassSignature = ClassType {+               ctsClassName = "java/lang/Object",+               ctsTypeArguments = []+           },+           csInterfaceSignatures = []+       })+  it "can handle the method signature of Iterator" $ do+    let sig = "(Ljava/util/function/Consumer<-TE;>;)V"+    parseOnly methodSignatureP sig `shouldBe`+      Right (MethodSignature {+          msTypeParameters = [],+          msArguments = [+              ReferenceType (RefClassType (ClassType {+                  ctsClassName = "java/util/function/Consumer",+                  ctsTypeArguments = [+                      Just (TypeArgument {+                          taWildcard = Just WildMinus,+                          taType = RefTypeVariable (TypeVariable {+                              tvAsText = "E"+                          })+                      })+                  ]+              }))+          ],+          msResults = Nothing,+          msThrows = []+      })+++  it "can handle the simple method signature" $ do+    parseOnly methodSignatureP "()V" `shouldBe` Right+        ( MethodSignature [] [] Nothing [])++  it "can handle throws method signature" $ do+    parseOnly (methodSignatureP <* endOfInput) "()V^TE;" `shouldBe` Right+        ( MethodSignature [] [] Nothing [ThrowsTypeVariable (TypeVariable "E")])++  it "can handle throws method signature with class" $ do+    parseOnly (methodSignatureP) "()V^Ljava/lang/Exception;" `shouldBe` Right+        ( MethodSignature [] [] Nothing [+                ThrowsClass (+                    ClassType {+                        ctsClassName = "java/lang/Exception"+                        , ctsTypeArguments = []+                        }+                    )+            ])++  it "can parse a type variable" $ do+    parseOnly typeVariableP "TE;" `shouldBe` Right (TypeVariable "E")++  it "can handle the simple field signature" $ do+    parseOnly fieldSignatureP "Ljava/util/function/Consumer<-TE;>;" `shouldBe` Right+        ( FieldSignature+          (RefClassType+           (ClassType "java/util/function/Consumer"+            [Just (TypeArgument (Just WildMinus) . RefTypeVariable $ TypeVariable "E") ]+           )))++ instance Arbitrary (Signature High) where   arbitrary = genericArbitraryU +instance Arbitrary (FieldSignature) where+  arbitrary = genericArbitraryU++instance Arbitrary (ReferenceType) where+  arbitrary = do+    n <- getSize+    if n == 0+      then pure (RefTypeVariable $ TypeVariable "X")+      else scale (\s -> s `div` 2) $ genericArbitraryU++instance Arbitrary (ClassType) where+  arbitrary = do+    s <- getSize+    n <- choose (0, s)+    x <- vectorOf n (resize (s `div` n) arbitrary)+    oneof+      [ ClassType <$> arbitrary <*> pure x+      , InnerClassType <$> elements ["a", "subclass"] <*> resize (n `div` 2) arbitrary <*> pure x+      ]+++instance Arbitrary (TypeVariable) where+  arbitrary = TypeVariable <$> elements ["A","B", "C", "HJ"]++instance Arbitrary (TypeSignature) where+  arbitrary = do+    n <- getSize+    if n == 0+    then BaseType <$> arbitrary+    else resize (n `div` 2) $ ReferenceType <$> arbitrary++instance Arbitrary (TypeArgument) where+  arbitrary = genericArbitraryU++instance Arbitrary (TypeParameter) where+  arbitrary = TypeParameter <$> elements ["A","B", "C", "HJ"] <*> arbitrary <*> arbitrary++instance Arbitrary (Wildcard) where+  arbitrary = genericArbitraryU++instance Arbitrary (MethodSignature) where+  arbitrary = genericArbitraryU++instance Arbitrary (ClassSignature) where+  arbitrary = genericArbitraryU++instance Arbitrary (ThrowsSignature) where+  arbitrary = genericArbitraryU  -- "Lcom/apple/eawt/_AppEventHandler$_AppEventDispatcher<Lcom/apple/eawt/QuitHandler;>;" -- "Lcom/apple/eawt/_AppEventHandler$_BooleanAppEventMultiplexor<Lcom/apple/eawt/ScreenSleepListener;Lcom/apple/eawt/AppEvent$ScreenSleepEvent;>;"
test/Language/JVM/ClassFileTest.hs view
@@ -19,7 +19,7 @@ prop_roundtrip_ClassFile = isoRoundtrip  instance Arbitrary (ClassAttributes High) where-  arbitrary = ClassAttributes <$> pure [] <*> pure [] <*> pure []+  arbitrary = pure $ ClassAttributes [] [] [] [] []  instance Arbitrary (ClassFile High) where   arbitrary = ClassFile
test/Language/JVM/TypeTest.hs view
@@ -4,32 +4,34 @@  import SpecHelper +import Data.Attoparsec.Text+import Data.Either import Language.JVM.Type  -- import Text.Megaparsec -- import Test.Hspec.Megaparsec --- spec_JType_parsing :: Spec--- spec_JType_parsing = do---   it "can parse \"[B\" as an array" $---     parse parseJType "" "[B" `shouldParse` JTArray JTByte---   it "can parse an array of strings" $---     parse parseJType "" "[Ljava/lang/String;" `shouldParse`---       JTArray (JTClass (ClassName "java/lang/String"))+spec_JType_parsing :: Spec+spec_JType_parsing = do+  it "can parse \"[B\" as an array" $+    parseOnly parseText "[B" `shouldBe` Right (JTArray (JTBase JTByte))+  it "can parse an array of strings" $+    parseOnly parseText "[Ljava/lang/String;" `shouldBe`+      Right (JTArray (JTClass (ClassName "java/lang/String"))) --- spec_MethodDescriptor_parsing :: Spec--- spec_MethodDescriptor_parsing = do---   it "can parse the empty method" $---     parse parseMethodDescriptor "" "()V" `shouldParse`---       MethodDescriptor [] Nothing---   it "can parse method arguments" $---     parse parseMethodDescriptor "" "(BZ)B" `shouldParse`---       MethodDescriptor [JTByte, JTBoolean] (Just JTByte)---   it "does not parse if there is too much" $---     methodDescriptorFromText "(BZ)Bx" `shouldBe` Nothing+spec_MethodDescriptor_parsing :: Spec+spec_MethodDescriptor_parsing = do+  it "can parse the empty method" $+    parseOnly parseText "()V" `shouldBe`+      Right (MethodDescriptor [] Nothing)+  it "can parse method arguments" $+    parseOnly parseText "(BZ)B" `shouldBe`+      Right (MethodDescriptor [JTBase JTByte, JTBase JTBoolean] (Just (JTBase JTByte)))+  it "does not parse if there is too much" $+    (fromText "(BZ)Bx" :: Either String MethodDescriptor) `shouldSatisfy` isLeft  instance Arbitrary ClassName where-  arbitrary = pure $ ClassName "package.Main"+  arbitrary = pure $ ClassName "package/Main"  instance Arbitrary JType where   arbitrary = genericArbitrary uniform
test/Language/JVMTest.hs view
@@ -41,11 +41,11 @@     cp `shouldSatisfy` isRight     let Right cp' = cp     forM_ (cMethods' cls) $ \m -> do-      case (runEvolve cp' (evolve m)) of+      case (runEvolve (EvolveConfig [] cp' (const True)) (evolve m)) of         Right _ -> return ()         Left err -> do           putStr (show err) >> putStr ": "-          print . runEvolve cp' $ do+          print . runEvolve (EvolveConfig [] cp' (const True)) $ do             x <- link (mDescriptor m)             n <- link (mName m)             return ((n, x) :: (MethodDescriptor, Text.Text))@@ -57,7 +57,7 @@                   putStr " -> " >> print i                  forM_ (C.codeAttributes c) $ \ca -> do-                  print $ runEvolve cp' (evolve ca)+                  print $ runEvolve (EvolveConfig [] cp' (const True)) (evolve ca)                   putStrLn (hexStringS $ aInfo ca)                   case fromAttribute' ca :: Either String (StackMapTable Low) of                     Right x ->@@ -76,7 +76,7 @@       decodeClassFile e `shouldBe` Right cls    describe "evolving/devolving" $ do-    let me = evolveClassFile cls+    let me = evolveClassFile (const True) cls     it "can evolve the whole class file" $ do       me `shouldSatisfy` isRight 
test/SpecHelper.hs view
@@ -1,4 +1,3 @@- module SpecHelper   ( module Test.Tasty   , module Test.Hspec.Expectations.Pretty@@ -14,6 +13,7 @@   , testAllFiles   , hexStringS   , hexString+  , withTestClass   , Spec   , SpecWith   , it@@ -42,6 +42,7 @@ import qualified Data.List as List  import Language.JVM.ByteCode+import Language.JVM.ClassFile import Language.JVM.Utils import Language.JVM.Staged import Language.JVM.ClassFileReader@@ -67,6 +68,10 @@       takeExtension p == ".class"       && p /= "test/data/SQLite.class" +withTestClass :: String -> IO (ClassFile High)+withTestClass str = do+  Right rf <- readClassFile <$> (blReadFile $ "test/data/" ++ str ++ ".class")+  return rf  -- testSomeFiles :: SpecWith BL.ByteString -> IO [TestTree] -- testSomeFiles spec =@@ -112,7 +117,7 @@       let bs = encode a'       a'' <- bimap trd trd $ decodeOrFail bs       cp' <- first show $ bootstrapConstantPool cp-      a3 <- first show $ runEvolve cp' (evolve a'')+      a3 <- first show $ runEvolve (EvolveConfig [] cp' (const True)) (evolve a'')       return (bs, a3)  -- | Test that a value can go from the Highest state to binary and back again@@ -133,7 +138,7 @@   let bs = encode a'   a'' <- bimap trd trd $ decodeOrFail bs   cp' <- first show $ bootstrapConstantPool cp-  a3 <- first show $ runEvolve cp' (evolveBC (return . fromIntegral) a'')+  a3 <- first show $ runEvolve (EvolveConfig [] cp' (const True)) (evolveBC (return . fromIntegral) a'')   return (bs, a3)  folderContents :: FilePath -> IO [ FilePath ]