module Language.Haskell.Tools.Refactor.GetModules where
import Control.Monad
import Control.Reference
import Data.Function (on)
import Data.List
import qualified Data.Map as Map
import Data.Maybe
import Distribution.Compiler
import Distribution.ModuleName (components)
import Distribution.ModuleName
import Distribution.Package (Dependency(..), PackageName(..), pkgName)
import Distribution.PackageDescription
import Distribution.PackageDescription.Configuration
import Distribution.PackageDescription.Parse
import Distribution.System
import Distribution.Verbosity (silent)
import Language.Haskell.Extension as Cabal
import System.Directory
import System.FilePath.Posix
import DynFlags
import qualified DynFlags as GHC
import GHC hiding (ModuleName)
import qualified Language.Haskell.TH.LanguageExtensions as GHC
import Name as GHC (Name)
import RdrName as GHC (RdrName)
import Language.Haskell.Tools.AST (Dom, IdDom)
import Language.Haskell.Tools.Refactor.RefactorBase
import Debug.Trace
data ModuleCollection
= ModuleCollection { _mcId :: ModuleCollectionId
, _mcRoot :: FilePath
, _mcSourceDirs :: [FilePath]
, _mcModules :: Map.Map SourceFileKey ModuleRecord
, _mcFlagSetup :: DynFlags -> IO DynFlags
, _mcLoadFlagSetup :: DynFlags -> IO DynFlags
, _mcDependencies :: [ModuleCollectionId]
}
instance Eq ModuleCollection where
(==) = (==) `on` _mcId
instance Show ModuleCollection where
show (ModuleCollection id root srcDirs mods _ _ deps)
= "ModuleCollection (" ++ show id ++ ") " ++ root ++ " " ++ show srcDirs ++ " (" ++ show mods ++ ") " ++ show deps
containingMC :: FilePath -> Simple Traversal [ModuleCollection] ModuleCollection
containingMC fp = traversal & filtered (\mc -> _mcRoot mc `isPrefixOf` fp)
data ModuleRecord
= ModuleNotLoaded { _recModuleWillNeedCode :: Bool }
| ModuleParsed { _parsedRecModule :: UnnamedModule (Dom RdrName)
, _modRecMS :: ModSummary
}
| ModuleRenamed { _renamedRecModule :: UnnamedModule (Dom Name)
, _modRecMS :: ModSummary
}
| ModuleTypeChecked { _typedRecModule :: UnnamedModule IdDom
, _modRecMS :: ModSummary
}
| ModuleCodeGenerated { _typedRecModule :: UnnamedModule IdDom
, _modRecMS :: ModSummary
}
data ModuleCollectionId = DirectoryMC FilePath
| LibraryMC String
| ExecutableMC String String
| TestSuiteMC String String
| BenchmarkMC String String
deriving (Eq, Ord, Show)
moduleCollectionIdString :: ModuleCollectionId -> String
moduleCollectionIdString (DirectoryMC fp) = fp
moduleCollectionIdString (LibraryMC id) = id
moduleCollectionIdString (ExecutableMC _ id) = id
moduleCollectionIdString (TestSuiteMC _ id) = id
moduleCollectionIdString (BenchmarkMC _ id) = id
moduleCollectionPkgId :: ModuleCollectionId -> Maybe String
moduleCollectionPkgId (DirectoryMC _) = Nothing
moduleCollectionPkgId (LibraryMC id) = Just id
moduleCollectionPkgId (ExecutableMC id _) = Just id
moduleCollectionPkgId (TestSuiteMC id _) = Just id
moduleCollectionPkgId (BenchmarkMC id _) = Just id
makeReferences ''ModuleCollection
makeReferences ''ModuleRecord
instance Show ModuleRecord where
show (ModuleNotLoaded code) = "ModuleNotLoaded " ++ show code
show mr@(ModuleParsed {}) = "ModuleParsed (" ++ (GHC.moduleNameString $ GHC.moduleName $ GHC.ms_mod $ fromJust $ mr ^? modRecMS) ++ ")"
show mr@(ModuleRenamed {}) = "ModuleRenamed (" ++ (GHC.moduleNameString $ GHC.moduleName $ GHC.ms_mod $ fromJust $ mr ^? modRecMS) ++ ")"
show mr@(ModuleTypeChecked {}) = "ModuleTypeChecked (" ++ (GHC.moduleNameString $ GHC.moduleName $ GHC.ms_mod $ fromJust $ mr ^? modRecMS) ++ ")"
show mr@(ModuleCodeGenerated {}) = "ModuleCodeGenerated (" ++ (GHC.moduleNameString $ GHC.moduleName $ GHC.ms_mod $ fromJust $ mr ^? modRecMS) ++ ")"
lookupModuleColl :: String -> [ModuleCollection] -> Maybe (ModuleCollection)
lookupModuleColl moduleName = find (any ((moduleName ==) . (^. sfkModuleName)) . Map.keys . (^. mcModules))
lookupModInSCs :: SourceFileKey -> [ModuleCollection] -> Maybe (SourceFileKey, ModuleRecord)
lookupModInSCs moduleName = find ((moduleName ==) . fst) . concatMap (Map.assocs . (^. mcModules))
removeModule :: String -> [ModuleCollection] -> [ModuleCollection]
removeModule moduleName = map (mcModules .- Map.filterWithKey (\k _ -> moduleName /= (k ^. sfkModuleName)))
hasGeneratedCode :: SourceFileKey -> [ModuleCollection] -> Bool
hasGeneratedCode key = maybe False (\case (_, ModuleCodeGenerated {}) -> True; _ -> False)
. find ((key ==) . fst) . concatMap (Map.assocs . (^. mcModules))
needsGeneratedCode :: SourceFileKey -> [ModuleCollection] -> Bool
needsGeneratedCode key = maybe False (\case (_, ModuleCodeGenerated {}) -> True; (_, ModuleNotLoaded True) -> True; _ -> False)
. find (((sfkIsBoot .= NormalHs $ key) ==) . fst) . concatMap (Map.assocs . (^. mcModules))
codeGeneratedFor :: SourceFileKey -> [ModuleCollection] -> [ModuleCollection]
codeGeneratedFor key = map (mcModules .- Map.adjust (\case (ModuleTypeChecked mod ms) -> ModuleCodeGenerated mod ms
ModuleNotLoaded _ -> ModuleNotLoaded True
r -> r) key)
isAlreadyLoaded :: SourceFileKey -> [ModuleCollection] -> Bool
isAlreadyLoaded key = maybe False (\case (_, ModuleNotLoaded {}) -> False; _ -> True)
. find ((key ==) . fst) . concatMap (Map.assocs . (^. mcModules))
getAllModules :: [FilePath] -> IO [ModuleCollection]
getAllModules pathes = orderMCs . concat <$> mapM getModules pathes
orderMCs :: [ModuleCollection] -> [ModuleCollection]
orderMCs = sortBy compareMCs
where compareMCs :: ModuleCollection -> ModuleCollection -> Ordering
compareMCs mc _ | DirectoryMC _ <- (mc ^. mcId) = GT
compareMCs _ mc | DirectoryMC _ <- (mc ^. mcId) = LT
compareMCs mc1 mc2 | (mc2 ^. mcId) `elem` (mc1 ^. mcDependencies) = GT
compareMCs mc1 mc2 | (mc1 ^. mcId) `elem` (mc2 ^. mcDependencies) = LT
compareMCs _ _ = EQ
getModules :: FilePath -> IO [ModuleCollection]
getModules root
= do files <- listDirectory root
case find (\p -> takeExtension p == ".cabal") files of
Just cabalFile -> modulesFromCabalFile root cabalFile
Nothing -> do mods <- modulesFromDirectory root root
return [ModuleCollection (DirectoryMC root) root [root] (Map.fromList $ map ((, ModuleNotLoaded False) . SourceFileKey NormalHs) mods) return return []]
modulesFromDirectory :: FilePath -> FilePath -> IO [String]
modulesFromDirectory root searchRoot = concat <$> (mapM goOn =<< listDirectory searchRoot)
where goOn fp = let path = searchRoot </> fp
in do isDir <- doesDirectoryExist path
if isDir
then modulesFromDirectory root path
else if takeExtension path == ".hs"
then return [concat $ intersperse "." $ splitDirectories $ dropExtension $ makeRelative root path]
else return []
srcDirFromRoot :: FilePath -> String -> FilePath
srcDirFromRoot fileName "" = fileName
srcDirFromRoot fileName moduleName
= srcDirFromRoot (takeDirectory fileName) (dropWhile (/= '.') $ dropWhile (== '.') moduleName)
modulesFromCabalFile :: FilePath -> FilePath -> IO [ModuleCollection]
modulesFromCabalFile root cabal = getModules . setupFlags <$> readPackageDescription silent (root </> cabal)
where getModules pkg = maybe [] (maybe [] (:[]) . toModuleCollection pkg) (library pkg)
++ catMaybes (map (toModuleCollection pkg) (executables pkg))
++ catMaybes (map (toModuleCollection pkg) (testSuites pkg))
++ catMaybes (map (toModuleCollection pkg) (benchmarks pkg))
toModuleCollection :: ToModuleCollection tmc => PackageDescription -> tmc -> Maybe ModuleCollection
toModuleCollection pkg tmc
= let bi = getBuildInfo tmc
in if buildable bi
then Just $ ModuleCollection (mkModuleCollKey (pkgName $ package pkg) tmc)
root
(map (normalise . (root </>)) $ hsSourceDirs bi)
(Map.fromList $ map ((, ModuleNotLoaded False) . SourceFileKey NormalHs . moduleName) (getModuleNames tmc))
(flagsFromBuildInfo bi)
(loadFlagsFromBuildInfo bi)
(map (\(Dependency pkgName _) -> LibraryMC (unPackageName pkgName)) (targetBuildDepends bi))
else Nothing
moduleName = concat . intersperse "." . components
setupFlags = either (\deps -> error $ "Missing dependencies: " ++ show deps) fst
. finalizePackageDescription [] (const True) buildPlatform
(unknownCompilerInfo buildCompilerId NoAbiTag) []
class ToModuleCollection t where
mkModuleCollKey :: PackageName -> t -> ModuleCollectionId
getBuildInfo :: t -> BuildInfo
getModuleNames :: t -> [ModuleName]
instance ToModuleCollection Library where
mkModuleCollKey pn _ = LibraryMC (unPackageName pn)
getBuildInfo = libBuildInfo
getModuleNames = libModules
instance ToModuleCollection Executable where
mkModuleCollKey pn exe = ExecutableMC (unPackageName pn) (exeName exe)
getBuildInfo = buildInfo
getModuleNames e = exeModules e
where toModuleName = map (\case c | c `elem` pathSeparators -> '.'; c -> c) . dropExtension
instance ToModuleCollection TestSuite where
mkModuleCollKey pn test = TestSuiteMC (unPackageName pn) (testName test)
getBuildInfo = testBuildInfo
getModuleNames = testModules
instance ToModuleCollection Benchmark where
mkModuleCollKey pn test = BenchmarkMC (unPackageName pn) (benchmarkName test)
getBuildInfo = benchmarkBuildInfo
getModuleNames = benchmarkModules
isDirectoryMC :: ModuleCollection -> Bool
isDirectoryMC mc = case mc ^. mcId of DirectoryMC{} -> True; _ -> False
compileInContext :: ModuleCollection -> [ModuleCollection] -> DynFlags -> IO DynFlags
compileInContext mc mcs dfs
= (\dfs' -> applyDependencies mcs (mc ^. mcDependencies) (selectEnabled dfs'))
<$> (mc ^. mcFlagSetup $ dfs)
where selectEnabled = if isDirectoryMC mc then id else onlyUseEnabled
applyDependencies :: [ModuleCollection] -> [ModuleCollectionId] -> DynFlags -> DynFlags
applyDependencies mcs ids dfs
= dfs { GHC.packageFlags = GHC.packageFlags dfs ++ (catMaybes $ map (dependencyToPkgFlag mcs) ids) }
onlyUseEnabled :: DynFlags -> DynFlags
onlyUseEnabled = GHC.setGeneralFlag' GHC.Opt_HideAllPackages
dependencyToPkgFlag :: [ModuleCollection] -> ModuleCollectionId -> Maybe (GHC.PackageFlag)
dependencyToPkgFlag mcs lib@(LibraryMC pkgName)
= if isNothing $ find (\mc -> (mc ^. mcId) == lib) mcs
then Just $ GHC.ExposePackage pkgName (GHC.PackageArg pkgName) (GHC.ModRenaming True [])
else Nothing
dependencyToPkgFlag _ _ = Nothing
setupLoadFlags :: [ModuleCollection] -> DynFlags -> IO DynFlags
setupLoadFlags mcs dfs = applyDependencies mcs allDeps . selectEnabled <$> useSavedFlags dfs
where allDeps = mcs ^? traversal & mcDependencies & traversal
selectEnabled = if any (\(mc,rest) -> isDirectoryMC mc && isIndependentMc mc rest) (breaks mcs) then id else onlyUseEnabled
useSavedFlags = foldl @[] (>=>) return (mcs ^? traversal & mcLoadFlagSetup)
isIndependentMc mc rest = not $ any (`isPrefixOf` (mc ^. mcRoot)) (map (^. mcRoot) rest)
breaks :: [a] -> [(a,[a])]
breaks [] = []
breaks (e:rest) = (e,rest) : map (\(x,ls) -> (x,e:ls)) (breaks rest)
loadFlagsFromBuildInfo :: BuildInfo -> DynFlags -> IO DynFlags
loadFlagsFromBuildInfo bi@BuildInfo{ cppOptions } df
= do (df',unused,warnings) <- parseDynamicFlags df (map (L noSrcSpan) $ cppOptions)
mapM_ putStrLn (map unLoc warnings ++ map (("Flag is not used: " ++) . unLoc) unused)
return (setupLoadExtensions df')
where setupLoadExtensions = foldl (.) id (map setExtensionFlag' $ catMaybes $ map translateExtension loadExtensions)
loadExtensions = [PatternSynonyms | patternSynonymsNeeded] ++ [ExplicitNamespaces | explicitNamespacesNeeded]
++ [PackageImports | packageImportsNeeded] ++ [CPP | cppNeeded] ++ [MagicHash | magicHashNeeded]
explicitNamespacesNeeded = not $ null $ map EnableExtension [ExplicitNamespaces, TypeFamilies, TypeOperators] `intersect` usedExtensions bi
patternSynonymsNeeded = EnableExtension PatternSynonyms `elem` usedExtensions bi
packageImportsNeeded = EnableExtension PackageImports `elem` usedExtensions bi
cppNeeded = EnableExtension CPP `elem` usedExtensions bi
magicHashNeeded = EnableExtension MagicHash `elem` usedExtensions bi
flagsFromBuildInfo :: BuildInfo -> DynFlags -> IO DynFlags
flagsFromBuildInfo bi@BuildInfo{ options } df
= do (df',unused,warnings) <- parseDynamicFlags df (map (L noSrcSpan) $ concatMap snd options)
mapM_ putStrLn (map unLoc warnings ++ map (("Flag is not used: " ++) . unLoc) unused)
return $ (flip lang_set (toGhcLang =<< defaultLanguage bi))
$ foldl (.) id (map (\case EnableExtension ext -> setEnabled True ext
DisableExtension ext -> setEnabled False ext
) (usedExtensions bi))
$ foldr (.) id (map (setEnabled True) (languageDefault (defaultLanguage bi)))
$ df'
where toGhcLang Cabal.Haskell98 = Just GHC.Haskell98
toGhcLang Cabal.Haskell2010 = Just GHC.Haskell2010
toGhcLang _ = Nothing
languageDefault (Just Cabal.Haskell2010)
= [ DatatypeContexts, DoAndIfThenElse, EmptyDataDecls, ForeignFunctionInterface
, PatternGuards, RelaxedPolyRec, TraditionalRecordSyntax ]
languageDefault _
= [ DatatypeContexts, NondecreasingIndentation, NPlusKPatterns, TraditionalRecordSyntax ]
setEnabled enable ext
= case translateExtension ext of
Just e -> (if enable then setExtensionFlag' else unSetExtensionFlag') e
Nothing -> id
setExtensionFlag', unSetExtensionFlag' :: GHC.Extension -> DynFlags -> DynFlags
setExtensionFlag' f dflags = foldr ($) (xopt_set dflags f) deps
where
deps = [ if turn_on then setExtensionFlag' d
else unSetExtensionFlag' d
| (f', turn_on, d) <- impliedXFlags, f' == f ]
unSetExtensionFlag' f dflags = xopt_unset dflags f
turnOn = True
turnOff = False
impliedXFlags :: [(GHC.Extension, Bool, GHC.Extension)]
impliedXFlags
= [ (GHC.RankNTypes, turnOn, GHC.ExplicitForAll)
, (GHC.ScopedTypeVariables, turnOn, GHC.ExplicitForAll)
, (GHC.LiberalTypeSynonyms, turnOn, GHC.ExplicitForAll)
, (GHC.ExistentialQuantification, turnOn, GHC.ExplicitForAll)
, (GHC.FlexibleInstances, turnOn, GHC.TypeSynonymInstances)
, (GHC.FunctionalDependencies, turnOn, GHC.MultiParamTypeClasses)
, (GHC.MultiParamTypeClasses, turnOn, GHC.ConstrainedClassMethods)
, (GHC.TypeFamilyDependencies, turnOn, GHC.TypeFamilies)
, (GHC.RebindableSyntax, turnOff, GHC.ImplicitPrelude)
, (GHC.GADTs, turnOn, GHC.GADTSyntax)
, (GHC.GADTs, turnOn, GHC.MonoLocalBinds)
, (GHC.TypeFamilies, turnOn, GHC.MonoLocalBinds)
, (GHC.TypeFamilies, turnOn, GHC.KindSignatures)
, (GHC.PolyKinds, turnOn, GHC.KindSignatures)
, (GHC.TypeInType, turnOn, GHC.DataKinds)
, (GHC.TypeInType, turnOn, GHC.PolyKinds)
, (GHC.TypeInType, turnOn, GHC.KindSignatures)
, (GHC.AutoDeriveTypeable, turnOn, GHC.DeriveDataTypeable)
, (GHC.TypeFamilies, turnOn, GHC.ExplicitNamespaces)
, (GHC.TypeOperators, turnOn, GHC.ExplicitNamespaces)
, (GHC.ImpredicativeTypes, turnOn, GHC.RankNTypes)
, (GHC.RecordWildCards, turnOn, GHC.DisambiguateRecordFields)
, (GHC.ParallelArrays, turnOn, GHC.ParallelListComp)
, (GHC.JavaScriptFFI, turnOn, GHC.InterruptibleFFI)
, (GHC.DeriveTraversable, turnOn, GHC.DeriveFunctor)
, (GHC.DeriveTraversable, turnOn, GHC.DeriveFoldable)
, (GHC.DuplicateRecordFields, turnOn, GHC.DisambiguateRecordFields)
, (GHC.TemplateHaskell, turnOn, GHC.TemplateHaskellQuotes)
, (GHC.Strict, turnOn, GHC.StrictData)
]
translateExtension AllowAmbiguousTypes = Just GHC.AllowAmbiguousTypes
translateExtension ApplicativeDo = Just GHC.ApplicativeDo
translateExtension Arrows = Just GHC.Arrows
translateExtension AutoDeriveTypeable = Just GHC.AutoDeriveTypeable
translateExtension BangPatterns = Just GHC.BangPatterns
translateExtension BinaryLiterals = Just GHC.BinaryLiterals
translateExtension CApiFFI = Just GHC.CApiFFI
translateExtension ConstrainedClassMethods = Just GHC.ConstrainedClassMethods
translateExtension ConstraintKinds = Just GHC.ConstraintKinds
translateExtension CPP = Just GHC.Cpp
translateExtension DataKinds = Just GHC.DataKinds
translateExtension DatatypeContexts = Just GHC.DatatypeContexts
translateExtension DefaultSignatures = Just GHC.DefaultSignatures
translateExtension DeriveAnyClass = Just GHC.DeriveAnyClass
translateExtension DeriveDataTypeable = Just GHC.DeriveDataTypeable
translateExtension DeriveFoldable = Just GHC.DeriveFoldable
translateExtension DeriveFunctor = Just GHC.DeriveFunctor
translateExtension DeriveGeneric = Just GHC.DeriveGeneric
translateExtension DeriveLift = Just GHC.DeriveLift
translateExtension DeriveTraversable = Just GHC.DeriveTraversable
translateExtension DisambiguateRecordFields = Just GHC.DisambiguateRecordFields
translateExtension DoAndIfThenElse = Just GHC.DoAndIfThenElse
translateExtension DoRec = Just GHC.RecursiveDo
translateExtension DuplicateRecordFields = Just GHC.DuplicateRecordFields
translateExtension EmptyCase = Just GHC.EmptyCase
translateExtension EmptyDataDecls = Just GHC.EmptyDataDecls
translateExtension ExistentialQuantification = Just GHC.ExistentialQuantification
translateExtension ExplicitForAll = Just GHC.ExplicitForAll
translateExtension ExplicitNamespaces = Just GHC.ExplicitNamespaces
translateExtension ExtendedDefaultRules = Just GHC.ExtendedDefaultRules
translateExtension FlexibleContexts = Just GHC.FlexibleContexts
translateExtension FlexibleInstances = Just GHC.FlexibleInstances
translateExtension ForeignFunctionInterface = Just GHC.ForeignFunctionInterface
translateExtension FunctionalDependencies = Just GHC.FunctionalDependencies
translateExtension GADTs = Just GHC.GADTs
translateExtension GADTSyntax = Just GHC.GADTSyntax
translateExtension GeneralizedNewtypeDeriving = Just GHC.GeneralizedNewtypeDeriving
translateExtension GHCForeignImportPrim = Just GHC.GHCForeignImportPrim
translateExtension ImplicitParams = Just GHC.ImplicitParams
translateExtension ImplicitPrelude = Just GHC.ImplicitPrelude
translateExtension ImpredicativeTypes = Just GHC.ImpredicativeTypes
translateExtension IncoherentInstances = Just GHC.IncoherentInstances
translateExtension InstanceSigs = Just GHC.InstanceSigs
translateExtension InterruptibleFFI = Just GHC.InterruptibleFFI
translateExtension JavaScriptFFI = Just GHC.JavaScriptFFI
translateExtension KindSignatures = Just GHC.KindSignatures
translateExtension LambdaCase = Just GHC.LambdaCase
translateExtension LiberalTypeSynonyms = Just GHC.LiberalTypeSynonyms
translateExtension MagicHash = Just GHC.MagicHash
translateExtension MonadComprehensions = Just GHC.MonadComprehensions
translateExtension MonadFailDesugaring = Just GHC.MonadFailDesugaring
translateExtension MonoLocalBinds = Just GHC.MonoLocalBinds
translateExtension MonomorphismRestriction = Just GHC.MonomorphismRestriction
translateExtension MonoPatBinds = Just GHC.MonoPatBinds
translateExtension MultiParamTypeClasses = Just GHC.MultiParamTypeClasses
translateExtension MultiWayIf = Just GHC.MultiWayIf
translateExtension NamedFieldPuns = Just GHC.RecordPuns
translateExtension NamedWildCards = Just GHC.NamedWildCards
translateExtension NegativeLiterals = Just GHC.NegativeLiterals
translateExtension NondecreasingIndentation = Just GHC.NondecreasingIndentation
translateExtension NPlusKPatterns = Just GHC.NPlusKPatterns
translateExtension NullaryTypeClasses = Just GHC.NullaryTypeClasses
translateExtension NumDecimals = Just GHC.NumDecimals
translateExtension OverlappingInstances = Just GHC.OverlappingInstances
translateExtension OverloadedLabels = Just GHC.OverloadedLabels
translateExtension OverloadedLists = Just GHC.OverloadedLists
translateExtension OverloadedStrings = Just GHC.OverloadedStrings
translateExtension PackageImports = Just GHC.PackageImports
translateExtension ParallelArrays = Just GHC.ParallelArrays
translateExtension ParallelListComp = Just GHC.ParallelListComp
translateExtension PartialTypeSignatures = Just GHC.PartialTypeSignatures
translateExtension PatternGuards = Just GHC.PatternGuards
translateExtension PatternSignatures = Just GHC.PatternSynonyms
translateExtension PatternSynonyms = Just GHC.PatternSynonyms
translateExtension PolyKinds = Just GHC.PolyKinds
translateExtension PostfixOperators = Just GHC.PostfixOperators
translateExtension QuasiQuotes = Just GHC.QuasiQuotes
translateExtension RankNTypes = Just GHC.RankNTypes
translateExtension RebindableSyntax = Just GHC.RebindableSyntax
translateExtension RecordPuns = Just GHC.RecordPuns
translateExtension RecordWildCards = Just GHC.RecordWildCards
translateExtension RecursiveDo = Just GHC.RecursiveDo
translateExtension RelaxedPolyRec = Just GHC.RelaxedPolyRec
translateExtension RestrictedTypeSynonyms = Nothing
translateExtension RoleAnnotations = Just GHC.RoleAnnotations
translateExtension ScopedTypeVariables = Just GHC.ScopedTypeVariables
translateExtension StandaloneDeriving = Just GHC.StandaloneDeriving
translateExtension StaticPointers = Just GHC.StaticPointers
translateExtension Strict = Just GHC.Strict
translateExtension StrictData = Just GHC.StrictData
translateExtension TemplateHaskell = Just GHC.TemplateHaskell
translateExtension TemplateHaskellQuotes = Just GHC.TemplateHaskellQuotes
translateExtension TraditionalRecordSyntax = Just GHC.TraditionalRecordSyntax
translateExtension TransformListComp = Just GHC.TransformListComp
translateExtension TupleSections = Just GHC.TupleSections
translateExtension TypeApplications = Just GHC.TypeApplications
translateExtension TypeFamilies = Just GHC.TypeFamilies
translateExtension TypeInType = Just GHC.TypeInType
translateExtension TypeOperators = Just GHC.TypeOperators
translateExtension TypeSynonymInstances = Just GHC.TypeSynonymInstances
translateExtension UnboxedTuples = Just GHC.UnboxedTuples
translateExtension UndecidableInstances = Just GHC.UndecidableInstances
translateExtension UndecidableSuperClasses = Just GHC.UndecidableSuperClasses
translateExtension UnicodeSyntax = Just GHC.UnicodeSyntax
translateExtension UnliftedFFITypes = Just GHC.UnliftedFFITypes
translateExtension ViewPatterns = Just GHC.ViewPatterns
translateExtension Safe = Nothing
translateExtension SafeImports = Nothing
translateExtension Trustworthy = Nothing
translateExtension Unsafe = Nothing
translateExtension Rank2Types = Just GHC.RankNTypes
translateExtension PolymorphicComponents = Just GHC.RankNTypes
translateExtension Generics = Nothing
translateExtension NewQualifiedOperators = Nothing
translateExtension ExtensibleRecords = Nothing
translateExtension XmlSyntax = Nothing
translateExtension HereDocuments = Nothing
translateExtension RegularPatterns = Nothing