inline-java 0.6.1 → 0.6.2
raw patch · 5 files changed
+66/−34 lines, 5 filesdep ~Cabaldep ~jnidep ~jvmnew-uploader
Dependency ranges changed: Cabal, jni, jvm
Files
- CHANGELOG.md +11/−0
- README.md +12/−4
- inline-java.cabal +4/−5
- src/Language/Java/Inline.hs +30/−24
- tests/Language/Java/InlineSpec.hs +9/−1
CHANGELOG.md view
@@ -4,6 +4,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). +## [0.6.2] - 2017-02-21++* Avoid producing warnings about unused inlinejava_bytecode0 bindings.+* Support type synonyms in variable antiquotation.+* Update lower bounds of jni to 0.3 and jvm to 0.2.++## [0.6.1] - 2016-12-27++* Support passing array objects as arguments / return values.+* More robust mangling of inline class name.+ ## [0.6.0] - 2016-12-13 ### Added
README.md view
@@ -9,13 +9,17 @@ **ahead of a new GHC release to build using GHC 8.0.2-rc2.** The Haskell standard includes a native foreign function interface-(FFI). It can be a pain to use and in any case only C support is+(FFI). Using it can be a bit involved and only C support is implemented in GHC. `inline-java` lets you call any JVM function directly, from Haskell, without the need to write your own foreign-import declarations using the FFI. In the style of `inline-c` for C and-`inline-r` for calling R, `inline-java` lets you name any function to-call inline in your code.+import declarations using the FFI. In the style of `inline-c` for+C and `inline-r` for calling R, `inline-java` lets you name any+function to call inline in your code. It is implemented on top of the+[jni][jni] and [jvm][jvm] packages. +[jni]: jni/+[jvm]: jvm/+ ## Example Graphical Hello World using Java Swing:@@ -47,6 +51,9 @@ * either, the [Nix][nix] package manager, * or, OpenJDK, Gradle and Spark (version 1.6) installed from your distro. +On OS X, you'll need to install the [Legacy Java SE 6][osx-java-se]+runtime when prompted, even when using Nix.+ To build: ```@@ -72,6 +79,7 @@ [stack]: https://github.com/commercialhaskell/stack [stack-nix]: https://docs.haskellstack.org/en/stable/nix_integration/#configuration [nix]: http://nixos.org/nix+[osx-java-se]: https://support.apple.com/kb/dl1572?locale=fr_FR ## License
inline-java.cabal view
@@ -1,5 +1,5 @@ name: inline-java-version: 0.6.1+version: 0.6.2 synopsis: Java interop via inline Java code in Haskell modules. description: Please see README.md. homepage: http://github.com/tweag/inline-java#readme@@ -31,15 +31,15 @@ base > 4.9.0.0 && < 5, binary >=0.7, bytestring >=0.10,- Cabal >= 1.24,+ Cabal >= 1.24.2, containers >=0.5, directory >=1.2, distributed-closure >=0.3, filepath >= 1, ghc-heap-view >= 0.5, inline-c >=0.5,- jni >= 0.1,- jvm >= 0.1,+ jni >= 0.3,+ jvm >= 0.2, language-java >= 0.2, process >= 1.2, singletons >= 2.0,@@ -69,4 +69,3 @@ singletons, text default-language: Haskell2010- extra-libraries: pthread
src/Language/Java/Inline.hs view
@@ -140,9 +140,9 @@ Right x -> x where pretty :: Sing (a :: JType) -> String- pretty (SClass sym) = JNI.toChars sym- pretty (SIface sym) = JNI.toChars sym- pretty (SPrim sym) = JNI.toChars sym+ pretty (SClass sym) = sym+ pretty (SIface sym) = sym+ pretty (SPrim sym) = sym pretty (SArray ty1) = pretty ty1 ++ "[]" pretty (SGeneric _ty1 _tys) = error "toJavaType(Generic): Unimplemented." pretty SVoid = "void"@@ -288,7 +288,7 @@ let klass = pkg ++ "/" ++ takeWhile (/= '.') classFile return $ DotClass (JNI.fromChars klass) bcode forM_ (zip dcs [(0 :: Int)..]) $ \(dc, i) -> do- ptr <- TH.newName $ "inlinejava__bytecode" ++ show i+ ptr <- TH.newName $ "_inlinejava__bytecode" ++ show i TH.addTopDecls =<< sequence [ TH.sigD ptr [t| StaticPtr DotClass |]@@ -342,30 +342,31 @@ info <- TH.reify name case info of #if MIN_VERSION_template_haskell(2,11,0)- TH.VarI _ (TH.AppT (TH.ConT nJ) thty) _-#else- TH.VarI _ (TH.AppT (TH.ConT nJ) thty) _ _-#endif- | nJ == ''J -> do- unliftJType thty >>= \case- SomeSing ty1 -> return $ (Java.Ident ('$':v), toJavaType ty1)-#if MIN_VERSION_template_haskell(2,11,0) TH.VarI _ ty _ -> do #else TH.VarI _ ty _ _ -> do #endif- targetty <- TH.newName "a"- instances <- TH.reifyInstances ''Coercible [ty, TH.VarT targetty]- jty <- case instances of- [TH.InstanceD _ _ (TH.AppT (TH.AppT _ _) thty) _] -> unliftJType thty >>= \case- SomeSing ty1 -> return $ toJavaType ty1- [] -> fail $ "No Coercible instance for type " ++ show (TH.ppr ty)- _ ->- fail $- "Ambiguous argument type " ++- show (TH.ppr ty) ++- ". Several Coercible instances apply."- return (Java.Ident ('$':v), jty)+ -- First (recursively) unfold type synonyms, if any.+ ty' <- unfoldHeadTySyn ty+ case ty' of+ TH.AppT (TH.ConT nJ) thty+ | nJ == ''J -> do+ unliftJType thty >>= \case+ SomeSing ty1 -> return $ (Java.Ident ('$':v), toJavaType ty1)+ _ -> do+ targetty <- TH.newName "a"+ instances <- TH.reifyInstances ''Coercible [ty, TH.VarT targetty]+ jty <- case instances of+ [TH.InstanceD _ _ (TH.AppT (TH.AppT _ _) thty) _] ->+ unliftJType thty >>= \case+ SomeSing ty1 -> return $ toJavaType ty1+ [] -> fail $ "No Coercible instance for type " ++ show (TH.ppr ty)+ _ ->+ fail $+ "Ambiguous argument type " +++ show (TH.ppr ty) +++ ". Several Coercible instances apply."+ return (Java.Ident ('$':v), jty) _ -> fail $ v ++ " not a valid variable name." let retty = toJavaType (SClass "java.lang.Object") return $ abstract@@ -395,3 +396,8 @@ -- returning boxed values. Once this limitation of the compiler gets -- lifted, we'll support returning unboxed values, just like `call` does. castReturnType funcall = [| unsafeUncoerce . coerce <$> $funcall |]+ unfoldHeadTySyn ty@(TH.ConT nT) = do+ TH.reify nT >>= \case+ TH.TyConI (TH.TySynD _ _ ty') -> unfoldHeadTySyn ty'+ _ -> return ty+ unfoldHeadTySyn ty = return ty
tests/Language/Java/InlineSpec.hs view
@@ -1,8 +1,10 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE ScopedTypeVariables #-}+-- Test that inline-java produces code without warnings.+{-# OPTIONS_GHC -Wall -Werror #-} -module Language.Java.InlineSpec where+module Language.Java.InlineSpec(spec) where import Data.Int import Foreign.JNI.Types (JObject)@@ -26,6 +28,12 @@ it "Supports antiquotation variables" $ do let x = 1 :: Int32 ([java| $x + 1 |] >>= reify) `shouldReturn` (2 :: Int32)++ it "Supports type synonym'ed antiquotation variables" $ do+ obj <- [java| new Object() {} |]+ let obj1 = obj :: JObject+ _ :: JObject <- [java| $obj1 |]+ return () it "Supports multiple antiquotation variables" $ do let foo = 1 :: Int32