Skip to content

Commit 4ac37d5

Browse files
committed
wip
1 parent 8ac0fb2 commit 4ac37d5

3 files changed

Lines changed: 44 additions & 16 deletions

File tree

app/Command/Compile.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,22 @@ targetParser =
131131
. T.unpack
132132
. T.strip
133133

134+
ffiExtensions :: Opts.Parser [String]
135+
ffiExtensions = Opts.option targetParser $
136+
Opts.long "ffi-exts"
137+
<> Opts.value ["js"]
138+
<> Opts.help
139+
( "Specifies comma-separated file extensions to consider for foriegn module implementations. "
140+
<> "Defaults to js"
141+
)
142+
134143
options :: Opts.Parser P.Options
135144
options =
136145
P.Options
137146
<$> verboseErrors
138147
<*> (not <$> comments)
139148
<*> (handleTargets <$> codegenTargets)
149+
<*> (S.fromList <$> ffiExtensions)
140150
where
141151
-- Ensure that the JS target is included if sourcemaps are
142152
handleTargets :: [P.CodegenTarget] -> S.Set P.CodegenTarget

src/Language/PureScript/Make.hs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ make ma@MakeActions{..} ms = do
283283
BuildPlan.markComplete buildPlan moduleName result
284284

285285
-- | Infer the module name for a module by looking for the same filename with
286-
-- a .js extension.
286+
-- a .js or .ts extension.
287287
inferForeignModules
288288
:: forall m
289289
. MonadIO m
@@ -295,8 +295,16 @@ inferForeignModules =
295295
inferForeignModule :: Either RebuildPolicy FilePath -> m (Maybe FilePath)
296296
inferForeignModule (Left _) = return Nothing
297297
inferForeignModule (Right path) = do
298-
let jsFile = replaceExtension path "js"
299-
exists <- liftIO $ doesFileExist jsFile
300-
if exists
298+
let
299+
jsFile = replaceExtension path "js"
300+
tsFile = replaceExtension path "ts"
301+
existsJs <- liftIO $ doesFileExist jsFile
302+
303+
if existsJs
301304
then return (Just jsFile)
302-
else return Nothing
305+
else do
306+
existsTs <- liftIO $ doesFileExist tsFile
307+
if existsTs
308+
then return (Just tsFile)
309+
else return Nothing
310+

src/Language/PureScript/Make/Actions.hs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ import Language.PureScript.Make.Cache (CacheDb, ContentHash, normaliseForCache)
5151
import Language.PureScript.Names (Ident(..), ModuleName, runModuleName)
5252
import Language.PureScript.Options (CodegenTarget(..), Options(..))
5353
import Language.PureScript.Pretty.Common (SMap(..))
54+
import Language.PureScript.PSString (mkString)
5455
import Paths_purescript qualified as Paths
5556
import SourceMap (generate)
5657
import SourceMap.Types (Mapping(..), Pos(..), SourceMapping(..))
5758
import System.Directory (getCurrentDirectory)
58-
import System.FilePath ((</>), makeRelative, splitPath, normalise, splitDirectories)
59+
import System.FilePath ((</>), makeRelative, splitPath, normalise, splitDirectories, takeExtension)
5960
import System.FilePath.Posix qualified as Posix
6061
import System.IO (stderr)
6162

@@ -256,11 +257,12 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
256257
lift $ writeJSONFile coreFnFile json
257258
when (S.member JS codegenTargets) $ do
258259
foreignInclude <- case mn `M.lookup` foreigns of
259-
Just _
260+
Just path
260261
| not $ requiresForeign m -> do
261262
return Nothing
262263
| otherwise -> do
263-
return $ Just "./foreign.js"
264+
let ext = if takeExtension path == ".ts" then ".ts" else ".js"
265+
return $ Just (mkString $ T.pack $ "./foreign" ++ ext)
264266
Nothing | requiresForeign m -> throwError . errorMessage' (CF.moduleSourceSpan m) $ MissingFFIModule mn
265267
| otherwise -> return Nothing
266268
rawJs <- J.moduleToJs m foreignInclude
@@ -331,12 +333,19 @@ data ForeignModuleType = ESModule | CJSModule deriving (Show)
331333
-- in its corresponding foreign module.
332334
checkForeignDecls :: CF.Module ann -> FilePath -> Make (Either MultipleErrors (ForeignModuleType, S.Set Ident))
333335
checkForeignDecls m path = do
334-
jsStr <- T.unpack <$> readTextFile path
335-
336-
let
337-
parseResult :: Either MultipleErrors JS.JSAST
338-
parseResult = first (errorParsingModule . Bundle.UnableToParseModule) $ JS.parseModule jsStr path
339-
traverse checkFFI parseResult
336+
if takeExtension path == ".js"
337+
then do
338+
jsStr <- T.unpack <$> readTextFile path
339+
340+
let
341+
parseResult :: Either MultipleErrors JS.JSAST
342+
parseResult = first (errorParsingModule . Bundle.UnableToParseModule) $ JS.parseModule jsStr path
343+
traverse checkFFI parseResult
344+
else do
345+
-- We cannot parse non-JS files to check for exports
346+
-- Instead return a successful ES module result without validation
347+
let foreignIdents = S.fromList (CF.moduleForeign m)
348+
return $ Right (ESModule, foreignIdents)
340349

341350
where
342351
mname = CF.moduleName m
@@ -451,5 +460,6 @@ ffiCodegen' foreigns codegenTargets makeOutputPath m = do
451460
where
452461
requiresForeign = not . null . CF.moduleForeign
453462

454-
copyForeign path mn =
455-
for_ makeOutputPath (\outputFilename -> copyFile path (outputFilename mn "foreign.js"))
463+
copyForeign path mn = do
464+
let ext = takeExtension path
465+
for_ makeOutputPath (\outputFilename -> copyFile path (outputFilename mn ("foreign" ++ ext)))

0 commit comments

Comments
 (0)