@@ -15,7 +15,7 @@ import qualified Control.Monad.Trans as T
1515import Control.Monad.Trans.State
1616import Data.Char
1717import Data.Maybe (fromJust)
18−import Data.List (isPrefixOf, intercalate)
18+import Data.List (isPrefixOf, isSuffixOf, intercalate)
1919import qualified Data.Text as T
2020import qualified Data.Text.IO as TIO
2121import Language.Java.Parser
@@ -35,9 +35,11 @@ type CodeGeneration = StateT (CodeGenerationEnv) (Either String)
3535codegenJava :: [(Name, SExp)] -> -- initialization of globals
3636 [(Name, SDecl)] ->
3737 FilePath -> -- output file name
38+ [String] -> -- headers
39+ [String] -> -- libs
3840 OutputType ->
3941 IO ()
40−codegenJava globalInit defs out exec = do
42+codegenJava globalInit defs out hdrs libs exec = do
4143 withTempdir (takeBaseName out) $ \ tmpDir -> do
4244 let srcdir = tmpDir </> "src" </> "main" </> "java"
4345 createDirectoryIfMissing True srcdir
@@ -46,7 +48,7 @@ codegenJava globalInit defs out exec = do
4648 let outjava = srcdir </> clsName <.> "java"
4749 let jout = either error
4850 (flatIndent . prettyPrint)
49− (evalStateT (mkCompilationUnit globalInit defs out) (mkCodeGenEnv globalInit))
51+ (evalStateT (mkCompilationUnit globalInit defs hdrs out) (mkCodeGenEnv globalInit))
5052 writeFile outjava jout
5153 if (exec == Raw)
5254 then copyFile outjava (takeDirectory out </> clsName <.> "java")
@@ -57,12 +59,16 @@ codegenJava globalInit defs out exec = do
5759 (T.pack clsName)
5860 (T.replace (T.pack "$ARTIFACT-NAME$")
5961 (T.pack $ takeBaseName out)
60− execPomTemplate)
62+ (T.replace (T.pack "$DEPENDENCIES$")
63+ (mkPomDependencies libs)
64+ execPomTemplate
65+ )
66+ )
6167 TIO.writeFile (tmpDir </> "pom.xml") execPom
6268 mvnCmd <- getMvn
6369 let args = ["-f", (tmpDir </> "pom.xml")]
64− (exit, _, err) <- readProcessWithExitCode mvnCmd (args ++ ["compile"]) ""
65− when (exit /= ExitSuccess) $ error ("FAILURE: " ++ mvnCmd ++ " compile\n" ++ err)
70+ (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ ["compile"]) ""
71+ when (exit /= ExitSuccess) $ error ("FAILURE: " ++ mvnCmd ++ " compile\n" ++ err ++ mvout)
6672 if (exec == Object)
6773 then do
6874 classFiles <-
@@ -72,8 +78,8 @@ codegenJava globalInit defs out exec = do
7278 mapM_ (\ clsFile -> copyFile clsFile (takeDirectory out </> takeFileName clsFile))
7379 classFiles
7480 else do
75− (exit, _, err) <- readProcessWithExitCode mvnCmd (args ++ ["package"]) ""
76− when (exit /= ExitSuccess) (error ("FAILURE: " ++ mvnCmd ++ " package\n" ++ err))
81+ (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ ["package"]) ""
82+ when (exit /= ExitSuccess) (error ("FAILURE: " ++ mvnCmd ++ " package\n" ++ err ++ mvout))
7783 copyFile (tmpDir </> "target" </> (takeBaseName out) <.> "jar") out
7884 handle <- openBinaryFile out ReadMode
7985 contents <- TIO.hGetContents handle
@@ -99,21 +105,40 @@ jarHeader =
99105 ++ "exec \"$java\" $java_args -jar $MYSELF \"$@\""
100106 ++ "exit 1\n"
101107
108+mkPomDependencies :: [String] -> T.Text
109+mkPomDependencies deps =
110+ T.concat $ map (T.concat . map (T.append (T.pack " ")) . mkDependency . T.pack) deps
111+ where
112+ mkDependency s =
113+ case T.splitOn (T.pack ":") s of
114+ [g, a, v] ->
115+ [ T.pack $ "<dependency>\n"
116+ , T.append (T.pack " ") $ mkGroupId g
117+ , T.append (T.pack " ") $ mkArtifactId a
118+ , T.append (T.pack " ") $ mkVersion v
119+ , T.pack $ "</dependency>\n"
120+ ]
121+ _ -> []
122+ mkGroupId g = T.append (T.pack $ "<groupId>") (T.append g $ T.pack "</groupId>\n")
123+ mkArtifactId a = T.append (T.pack $ "<artifactId>") (T.append a $ T.pack "</artifactId>\n")
124+ mkVersion v = T.append (T.pack $ "<version>") (T.append v $ T.pack "</version>\n")
125+
102126mkCodeGenEnv :: [(Name, SExp)] -> CodeGenerationEnv
103127mkCodeGenEnv globalInit =
104128 CodeGenerationEnv $ zipWith (\ (name, _) pos -> (name, pos)) globalInit [0..]
105129
106−mkCompilationUnit :: [(Name, SExp)] -> [(Name, SDecl)] -> FilePath -> CodeGeneration CompilationUnit
107−mkCompilationUnit globalInit defs out =
108− CompilationUnit Nothing [ ImportDecl False idrisRts True
109− , ImportDecl True idrisForeign True
110− , ImportDecl False bigInteger False
111− , ImportDecl False stringBuffer False
112− , ImportDecl False runtimeException False
113− , ImportDecl False scanner False
114− , ImportDecl False arrays False
115− ] <$>
116− mkTypeDecl globalInit defs out
130+mkCompilationUnit :: [(Name, SExp)] -> [(Name, SDecl)] -> [String] -> FilePath -> CodeGeneration CompilationUnit
131+mkCompilationUnit globalInit defs hdrs out =
132+ CompilationUnit Nothing ( [ ImportDecl False idrisRts True
133+ , ImportDecl True idrisForeign True
134+ , ImportDecl False bigInteger False
135+ , ImportDecl False stringBuffer False
136+ , ImportDecl False runtimeException False
137+ , ImportDecl False scanner False
138+ , ImportDecl False arrays False
139+ ] ++ otherHdrs
140+ )
141+ <$> mkTypeDecl globalInit defs out
117142 where
118143 idrisRts = J.Name $ map Ident ["org", "idris", "rts"]
119144 idrisForeign = J.Name $ map Ident ["org", "idris", "rts", "ForeignPrimitives"]
@@ -122,6 +147,12 @@ mkCompilationUnit globalInit defs out =
122147 runtimeException = J.Name $ map Ident ["java", "lang", "RuntimeException"]
123148 scanner = J.Name $ map Ident ["java", "util", "Scanner"]
124149 arrays = J.Name $ map Ident ["java", "util", "Arrays"]
150+ otherHdrs = map ( (\ name -> ImportDecl False name False)
151+ . J.Name
152+ . map (Ident . T.unpack)
153+ . T.splitOn (T.pack ".")
154+ . T.pack)
155+ $ filter (not . isSuffixOf ".h") hdrs
125156
126157flatIndent :: String -> String
127158flatIndent (' ' : ' ' : xs) = flatIndent xs