2014-09-12 01:48:22 +00:00
|
|
|
{-# LANGUAGE CPP #-}
|
2014-07-18 05:05:20 +00:00
|
|
|
module Language.Haskell.GhcMod.Target (
|
|
|
|
setTargetFiles
|
|
|
|
) where
|
2015-03-03 19:28:34 +00:00
|
|
|
-- ghc-mod: Making Haskell development *more* fun
|
|
|
|
-- Copyright (C) 2015 Daniel Gröber <dxld ÄT darkboxed DOT org>
|
|
|
|
--
|
|
|
|
-- This program is free software: you can redistribute it and/or modify
|
|
|
|
-- it under the terms of the GNU Affero General Public License as published by
|
|
|
|
-- the Free Software Foundation, either version 3 of the License, or
|
|
|
|
-- (at your option) any later version.
|
|
|
|
--
|
|
|
|
-- This program is distributed in the hope that it will be useful,
|
|
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
-- GNU Affero General Public License for more details.
|
|
|
|
--
|
|
|
|
-- You should have received a copy of the GNU Affero General Public License
|
|
|
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2014-07-18 05:05:20 +00:00
|
|
|
|
|
|
|
import Control.Applicative ((<$>))
|
|
|
|
import Control.Monad (forM, void, (>=>))
|
|
|
|
import DynFlags (ExtensionFlag(..), xopt)
|
2014-09-12 01:48:22 +00:00
|
|
|
import GHC (LoadHowMuch(..))
|
2014-07-18 05:05:20 +00:00
|
|
|
import qualified GHC as G
|
|
|
|
import Language.Haskell.GhcMod.DynFlags
|
2014-07-19 02:53:05 +00:00
|
|
|
import Language.Haskell.GhcMod.Monad
|
2014-07-18 05:05:20 +00:00
|
|
|
|
|
|
|
-- | Set the files as targets and load them.
|
|
|
|
setTargetFiles :: IOish m => [FilePath] -> GhcModT m ()
|
|
|
|
setTargetFiles files = do
|
|
|
|
targets <- forM files $ \file -> G.guessTarget file Nothing
|
|
|
|
G.setTargets targets
|
2014-08-12 16:09:31 +00:00
|
|
|
mode <- getCompilerMode
|
2014-07-19 02:53:05 +00:00
|
|
|
if mode == Intelligent then
|
|
|
|
loadTargets Intelligent
|
|
|
|
else do
|
|
|
|
mdls <- G.depanal [] False
|
|
|
|
let fallback = needsFallback mdls
|
|
|
|
if fallback then do
|
|
|
|
resetTargets targets
|
|
|
|
setIntelligent
|
|
|
|
loadTargets Intelligent
|
|
|
|
else
|
|
|
|
loadTargets Simple
|
2014-07-18 05:05:20 +00:00
|
|
|
where
|
2014-07-19 02:53:05 +00:00
|
|
|
loadTargets Simple = do
|
2014-07-18 05:05:20 +00:00
|
|
|
-- Reporting error A and error B
|
|
|
|
void $ G.load LoadAllTargets
|
|
|
|
mss <- filter (\x -> G.ms_hspp_file x `elem` files) <$> G.getModuleGraph
|
|
|
|
-- Reporting error B and error C
|
|
|
|
mapM_ (G.parseModule >=> G.typecheckModule >=> G.desugarModule) mss
|
|
|
|
-- Error B duplicates. But we cannot ignore both error reportings,
|
|
|
|
-- sigh. So, the logger makes log messages unique by itself.
|
2014-07-19 02:53:05 +00:00
|
|
|
loadTargets Intelligent = do
|
2014-07-18 05:05:20 +00:00
|
|
|
df <- G.getSessionDynFlags
|
|
|
|
void $ G.setSessionDynFlags (setModeIntelligent df)
|
|
|
|
void $ G.load LoadAllTargets
|
2014-07-19 02:53:05 +00:00
|
|
|
resetTargets targets = do
|
|
|
|
G.setTargets []
|
|
|
|
void $ G.load LoadAllTargets
|
|
|
|
G.setTargets targets
|
|
|
|
setIntelligent = do
|
|
|
|
newdf <- setModeIntelligent <$> G.getSessionDynFlags
|
|
|
|
void $ G.setSessionDynFlags newdf
|
2014-07-22 17:45:48 +00:00
|
|
|
setCompilerMode Intelligent
|
2014-07-18 05:05:20 +00:00
|
|
|
|
|
|
|
needsFallback :: G.ModuleGraph -> Bool
|
2014-09-12 01:48:22 +00:00
|
|
|
needsFallback = any $ \ms ->
|
|
|
|
let df = G.ms_hspp_opts ms in
|
|
|
|
Opt_TemplateHaskell `xopt` df
|
|
|
|
|| Opt_QuasiQuotes `xopt` df
|
|
|
|
#if __GLASGOW_HASKELL__ >= 708
|
|
|
|
|| (Opt_PatternSynonyms `xopt` df)
|
|
|
|
#endif
|