From 3610dff1b8308a810d827f0595832b326deff37b Mon Sep 17 00:00:00 2001 From: eric thul Date: Sat, 18 Jul 2015 17:07:38 -0400 Subject: Add FFI JavaScript as a webpack dependency Resolves #18 --- src/FS.purs | 35 +++++++++++++++++++++++++++++++++++ src/Loader.purs | 23 ++++++++++++++++++++--- src/LoaderRef.purs | 24 ++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/FS.purs b/src/FS.purs index a56fe26..6955a63 100644 --- a/src/FS.purs +++ b/src/FS.purs @@ -1,12 +1,16 @@ module PursLoader.FS ( FS() , writeFileUtf8 + , findFileUtf8 ) where import Control.Monad.Aff (Aff(), makeAff) import Control.Monad.Eff (Eff()) import Control.Monad.Eff.Exception (Error()) +import Data.Maybe (Maybe(..)) +import Data.String.Regex (Regex()) + import Data.Function foreign import data FS :: ! @@ -30,3 +34,34 @@ function writeFileUtf8Fn(filepath, contents, errback, callback) { (Error -> Eff (fs :: FS | eff) Unit) (Unit -> Eff (fs :: FS | eff) Unit) (Eff (fs :: FS | eff) Unit) + +findFileUtf8 :: forall eff. Regex -> [String] -> Aff (fs :: FS | eff) (Maybe String) +findFileUtf8 regexp filepaths = makeAff $ runFn6 findFileUtf8Fn Nothing Just regexp filepaths + +foreign import findFileUtf8Fn """ +function findFileUtf8Fn(nothing, just, regex, filepaths, errback, callback) { + return function(){ + var fs = require('fs'); + + var async = require('async'); + + function findFile(filepath, callback) { + fs.readFile(filepath, {encoding: 'utf-8'}, function(error, result){ + if (error) callback(false); + else callback(regex.test(result)); + }); + } + + async.detect(filepaths, findFile, function(result){ + if (!result) callback(nothing)(); + else callback(just(result))(); + }); + }; +} +""" :: forall eff. Fn6 (Maybe String) + (String -> Maybe String) + Regex + [String] + (Error -> Eff (fs :: FS | eff) Unit) + (Maybe String -> Eff (fs :: FS | eff) Unit) + (Eff (fs :: FS | eff) Unit) diff --git a/src/Loader.purs b/src/Loader.purs index 872a51c..e9e03c4 100644 --- a/src/Loader.purs +++ b/src/Loader.purs @@ -13,12 +13,12 @@ import Data.Array ((!!), concat) import Data.Function (Fn2(), mkFn2) import Data.Maybe (Maybe(..), fromMaybe, maybe) import Data.String (joinWith) -import Data.String.Regex (match, noFlags, regex) +import Data.String.Regex (match, noFlags, regex, test) import PursLoader.ChildProcess (ChildProcess(), spawn) -import PursLoader.FS (FS(), writeFileUtf8) +import PursLoader.FS (FS(), writeFileUtf8, findFileUtf8) import PursLoader.Glob (Glob(), globAll) -import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query) +import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query, clearDependencies, addDependency, resourcePath) import PursLoader.LoaderUtil (parseQuery) import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions) @@ -26,6 +26,8 @@ type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true } +foreignRegex = regex "(?:^|\\n)\\s*foreign import\\s+" noFlags { ignoreCase = true } + pscCommand = "psc" psciCommand = "psci" @@ -54,6 +56,11 @@ mkPsci srcs ffis = joinWith "\n" ((loadModule <$> concat srcs) <> (loadForeign < loadForeign :: String -> String loadForeign a = ":f " ++ relative cwd a +findFFI :: forall eff. [[String]] -> String -> Aff (fs :: FS | eff) (Maybe String) +findFFI ffiss name = findFileUtf8 re (concat ffiss) + where + re = regex ("(?:^|\\n)//\\s*module\\s*" ++ name ++ "\\s*\\n") noFlags + loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String) loader' ref source = do liftEff $ cacheable ref @@ -73,8 +80,18 @@ loader' ref source = do writeFileUtf8 psciFilename psciFile let moduleName = match moduleRegex source >>= (!!!) 1 + hasForeign = test foreignRegex source result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName + liftEff (clearDependencies ref) + liftEff (addDependency ref (resourcePath ref)) + + foreignPath <- if hasForeign + then fromMaybe (pure Nothing) (findFFI ffiss <$> moduleName) + else pure Nothing + + fromMaybe (pure unit) ((\path -> liftEff (addDependency ref path)) <$> foreignPath) + return result loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit diff --git a/src/LoaderRef.purs b/src/LoaderRef.purs index 2567b1e..f1efa04 100644 --- a/src/LoaderRef.purs +++ b/src/LoaderRef.purs @@ -4,6 +4,9 @@ module PursLoader.LoaderRef , async , cacheable , query + , clearDependencies + , addDependency + , resourcePath ) where import Control.Monad.Eff (Eff()) @@ -48,3 +51,24 @@ foreign import query """ function query(ref){ return ref.query; }""" :: LoaderRef -> String + +foreign import clearDependencies """ +function clearDependencies(ref){ + return function(){ + return ref.clearDependencies(); + }; +}""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit + +foreign import resourcePath """ +function resourcePath(ref){ + return ref.resourcePath; +}""" :: LoaderRef -> String + +foreign import addDependency """ +function addDependency(ref){ + return function(dep){ + return function(){ + return ref.addDependency(dep); + }; + }; +}""" :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit -- cgit v1.2.3