Export some useful GHC API functions.
authorEdward Z. Yang <ezyang@cs.stanford.edu>
Tue, 29 Dec 2015 12:43:02 +0000 (13:43 +0100)
committerBen Gamari <ben@smart-cactus.org>
Tue, 29 Dec 2015 13:13:34 +0000 (14:13 +0100)
Working on some code using the GHC API, I found these
functions were useful and wished they were exported.  This
commit exports them.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Test Plan: validate

Reviewers: austin, bgamari

Reviewed By: bgamari

Subscribers: hvr, thomie

Differential Revision: https://phabricator.haskell.org/D1710

compiler/main/DriverPhases.hs
compiler/main/DriverPipeline.hs
compiler/main/Finder.hs
compiler/main/GhcMake.hs
ghc/Main.hs

index ff6f8b8..84eee1b 100644 (file)
@@ -25,6 +25,8 @@ module DriverPhases (
    isHaskellSigSuffix,
    isSourceSuffix,
 
+   isHaskellishTarget,
+
    isHaskellishFilename,
    isHaskellSrcFilename,
    isHaskellSigFilename,
@@ -42,6 +44,7 @@ import Outputable
 import Platform
 import System.FilePath
 import Binary
+import Util
 
 -----------------------------------------------------------------------------
 -- Phases
@@ -333,6 +336,23 @@ isDynLibSuffix platform s = s `elem` dynlib_suffixes platform
 isSourceSuffix :: String -> Bool
 isSourceSuffix suff  = isHaskellishSuffix suff || isCishSuffix suff
 
+-- | When we are given files (modified by -x arguments) we need
+-- to determine if they are Haskellish or not to figure out
+-- how we should try to compile it.  The rules are:
+--
+--      1. If no -x flag was specified, we check to see if
+--         the file looks like a module name, has no extension,
+--         or has a Haskell source extension.
+--
+--      2. If an -x flag was specified, we just make sure the
+--         specified suffix is a Haskell one.
+isHaskellishTarget :: (String, Maybe Phase) -> Bool
+isHaskellishTarget (f,Nothing) =
+  looksLikeModuleName f || isHaskellSrcFilename f || '.' `notElem` f
+isHaskellishTarget (_,Just phase) =
+  phase `notElem` [ As True, As False, Cc, Cobjc, Cobjcxx, CmmCpp, Cmm
+                  , StopLn]
+
 isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
     isHaskellUserSrcFilename, isSourceFilename, isHaskellSigFilename
  :: FilePath -> Bool
index ee07d54..4936ace 100644 (file)
@@ -25,7 +25,7 @@ module DriverPipeline (
 
         -- Exports for hooks to override runPhase and link
    PhasePlus(..), CompPipeline(..), PipeEnv(..), PipeState(..),
-   phaseOutputFilename, getPipeState, getPipeEnv,
+   phaseOutputFilename, getOutputFilename, getPipeState, getPipeEnv,
    hscPostBackendPhase, getLocation, setModLocation, setDynFlags,
    runPhase, exeFileName,
    mkExtraObjToLinkIntoBinary, mkNoteObjsToLinkIntoBinary,
@@ -708,6 +708,9 @@ runHookedPhase pp input dflags =
 -- output.  All the logic about which filenames we generate output
 -- into is embodied in the following function.
 
+-- | Computes the next output filename after we run @next_phase@.
+-- Like 'getOutputFilename', but it operates in the 'CompPipeline' monad
+-- (which specifies all of the ambient information.)
 phaseOutputFilename :: Phase{-next phase-} -> CompPipeline FilePath
 phaseOutputFilename next_phase = do
   PipeEnv{stop_phase, src_basename, output_spec} <- getPipeEnv
@@ -716,6 +719,21 @@ phaseOutputFilename next_phase = do
   liftIO $ getOutputFilename stop_phase output_spec
                              src_basename dflags next_phase maybe_loc
 
+-- | Computes the next output filename for something in the compilation
+-- pipeline.  This is controlled by several variables:
+--
+--      1. 'Phase': the last phase to be run (e.g. 'stopPhase').  This
+--         is used to tell if we're in the last phase or not, because
+--         in that case flags like @-o@ may be important.
+--      2. 'PipelineOutput': is this intended to be a 'Temporary' or
+--         'Persistent' build output?  Temporary files just go in
+--         a fresh temporary name.
+--      3. 'String': what was the basename of the original input file?
+--      4. 'DynFlags': the obvious thing
+--      5. 'Phase': the phase we want to determine the output filename of.
+--      6. @Maybe ModLocation@: the 'ModLocation' of the module we're
+--         compiling; this can be used to override the default output
+--         of an object file.  (TODO: do we actually need this?)
 getOutputFilename
   :: Phase -> PipelineOutput -> String
   -> DynFlags -> Phase{-next phase-} -> Maybe ModLocation -> IO FilePath
index dddc09a..2ac0737 100644 (file)
@@ -17,6 +17,8 @@ module Finder (
     mkHomeModLocation,
     mkHomeModLocation2,
     mkHiOnlyModLocation,
+    mkHiPath,
+    mkObjPath,
     addHomeModuleToFinder,
     uncacheModule,
     mkStubPaths,
index 843def1..9c6abb8 100644 (file)
@@ -18,6 +18,8 @@ module GhcMake(
 
         topSortModuleGraph,
 
+        ms_home_srcimps, ms_home_imps,
+
         noModError, cyclicModuleErr
     ) where
 
@@ -1709,9 +1711,15 @@ home_imps imps = [ lmodname |  (mb_pkg, lmodname) <- imps,
 ms_home_allimps :: ModSummary -> [ModuleName]
 ms_home_allimps ms = map unLoc (ms_home_srcimps ms ++ ms_home_imps ms)
 
+-- | Like 'ms_home_imps', but for SOURCE imports.
 ms_home_srcimps :: ModSummary -> [Located ModuleName]
 ms_home_srcimps = home_imps . ms_srcimps
 
+-- | All of the (possibly) home module imports from a
+-- 'ModSummary'; that is to say, each of these module names
+-- could be a home import if an appropriately named file
+-- existed.  (This is in contrast to package qualified
+-- imports, which are guaranteed not to be home imports.)
 ms_home_imps :: ModSummary -> [Located ModuleName]
 ms_home_imps = home_imps . ms_imps
 
index 31a9b91..73552d3 100644 (file)
@@ -694,13 +694,7 @@ addFlag s flag = liftEwM $ do
 
 doMake :: [(String,Maybe Phase)] -> Ghc ()
 doMake srcs  = do
-    let (hs_srcs, non_hs_srcs) = partition haskellish srcs
-
-        haskellish (f,Nothing) =
-          looksLikeModuleName f || isHaskellSrcFilename f || '.' `notElem` f
-        haskellish (_,Just phase) =
-          phase `notElem` [ As True, As False, Cc, Cobjc, Cobjcxx, CmmCpp, Cmm
-                          , StopLn]
+    let (hs_srcs, non_hs_srcs) = partition isHaskellishTarget srcs
 
     hsc_env <- GHC.getSession