{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE CPP #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Language.Haskell.Exts.Extension
-- Copyright   :  (c) Niklas Broberg 2009
-- License     :  BSD-style (see the file LICENSE.txt)
--
-- Maintainer  :  Niklas Broberg, niklas.broberg@chalmers.se
-- Stability   :  transient
-- Portability :  portable
--
-- This module defines the list of recognized modular features
-- of Haskell, most often (sloppily) referred to as "extensions".
--
-- Closely mimicking the Language.Haskell.Extension module from
-- the Cabal library, this package also includes functionality for
-- "computing" languages as sets of features. Also, we make no
-- promise not to add extensions not yet recognized by Cabal.
--
-----------------------------------------------------------------------------
module Language.Haskell.Exts.Extension (
    -- * Language definitions
    Language(..),
    knownLanguages,
    classifyLanguage,
    prettyLanguage,

    -- * Extensions
    Extension(..), KnownExtension(..),
    classifyExtension,
    parseExtension, prettyExtension,

    -- * Extension groups
    ghcDefault, glasgowExts,
    knownExtensions, deprecatedExtensions,

    -- * Semantics of extensions applied to languages
    impliesExts, toExtensionList

    ) where

#if __GLASGOW_HASKELL__ < 710
import Control.Applicative ((<$>), (<|>))
#else
import Control.Applicative ((<|>))
#endif
import Data.Array (Array, accumArray, bounds, Ix(inRange), (!))
import Data.List (nub)
import Data.Maybe (fromMaybe)
import Data.Data

-- Copyright notice from Cabal's Language.Haskell.Extension,
-- from which we borrow plenty of features:

{- All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of Isaac Jones nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}

data Language =

  -- | The Haskell 98 language as defined by the Haskell 98 report.
  -- <http://haskell.org/onlinereport/>
     Haskell98

  -- | The Haskell 2010 language as defined by the Haskell 2010 report.
  -- <http://www.haskell.org/onlinereport/haskell2010>
  | Haskell2010

  -- | The minimal language resulting from disabling all recognized
  -- extensions - including ones that are part of all known language
  -- definitions e.g. MonomorphismRestriction.
  | HaskellAllDisabled

  -- | An unknown language, identified by its name.
  | UnknownLanguage String
  deriving (Int -> Language -> ShowS
[Language] -> ShowS
Language -> String
(Int -> Language -> ShowS)
-> (Language -> String) -> ([Language] -> ShowS) -> Show Language
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Language -> ShowS
showsPrec :: Int -> Language -> ShowS
$cshow :: Language -> String
show :: Language -> String
$cshowList :: [Language] -> ShowS
showList :: [Language] -> ShowS
Show, ReadPrec [Language]
ReadPrec Language
Int -> ReadS Language
ReadS [Language]
(Int -> ReadS Language)
-> ReadS [Language]
-> ReadPrec Language
-> ReadPrec [Language]
-> Read Language
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Language
readsPrec :: Int -> ReadS Language
$creadList :: ReadS [Language]
readList :: ReadS [Language]
$creadPrec :: ReadPrec Language
readPrec :: ReadPrec Language
$creadListPrec :: ReadPrec [Language]
readListPrec :: ReadPrec [Language]
Read, Language -> Language -> Bool
(Language -> Language -> Bool)
-> (Language -> Language -> Bool) -> Eq Language
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Language -> Language -> Bool
== :: Language -> Language -> Bool
$c/= :: Language -> Language -> Bool
/= :: Language -> Language -> Bool
Eq, Eq Language
Eq Language =>
(Language -> Language -> Ordering)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Language)
-> (Language -> Language -> Language)
-> Ord Language
Language -> Language -> Bool
Language -> Language -> Ordering
Language -> Language -> Language
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Language -> Language -> Ordering
compare :: Language -> Language -> Ordering
$c< :: Language -> Language -> Bool
< :: Language -> Language -> Bool
$c<= :: Language -> Language -> Bool
<= :: Language -> Language -> Bool
$c> :: Language -> Language -> Bool
> :: Language -> Language -> Bool
$c>= :: Language -> Language -> Bool
>= :: Language -> Language -> Bool
$cmax :: Language -> Language -> Language
max :: Language -> Language -> Language
$cmin :: Language -> Language -> Language
min :: Language -> Language -> Language
Ord, Typeable Language
Typeable Language =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Language -> c Language)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Language)
-> (Language -> Constr)
-> (Language -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Language))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language))
-> ((forall b. Data b => b -> b) -> Language -> Language)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Language -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Language -> r)
-> (forall u. (forall d. Data d => d -> u) -> Language -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Language -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Language -> m Language)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Language -> m Language)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Language -> m Language)
-> Data Language
Language -> Constr
Language -> DataType
(forall b. Data b => b -> b) -> Language -> Language
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Language -> u
forall u. (forall d. Data d => d -> u) -> Language -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Language -> m Language
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Language
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Language -> c Language
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Language)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Language -> c Language
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Language -> c Language
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Language
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Language
$ctoConstr :: Language -> Constr
toConstr :: Language -> Constr
$cdataTypeOf :: Language -> DataType
dataTypeOf :: Language -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Language)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Language)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language)
$cgmapT :: (forall b. Data b => b -> b) -> Language -> Language
gmapT :: (forall b. Data b => b -> b) -> Language -> Language
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Language -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Language -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Language -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Language -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Language -> m Language
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Language -> m Language
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
Data, Typeable)

knownLanguages :: [Language]
knownLanguages :: [Language]
knownLanguages = [Language
Haskell98, Language
Haskell2010]

classifyLanguage :: String -> Language
classifyLanguage :: String -> Language
classifyLanguage String
str = Language -> Maybe Language -> Language
forall a. a -> Maybe a -> a
fromMaybe (String -> Language
UnknownLanguage String
str) (Maybe Language -> Language) -> Maybe Language -> Language
forall a b. (a -> b) -> a -> b
$ String -> [(String, Language)] -> Maybe Language
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
str [(String, Language)]
langTable
  where
    langTable :: [(String, Language)]
langTable = [ (Language -> String
forall a. Show a => a -> String
show Language
lang, Language
lang)
                | Language
lang <- [Language]
knownLanguages ]

prettyLanguage :: Language -> String
prettyLanguage :: Language -> String
prettyLanguage (UnknownLanguage String
name) = String
name
prettyLanguage Language
lang = Language -> String
forall a. Show a => a -> String
show Language
lang

-- | This represents language extensions beyond a base 'Language' definition
-- (such as 'Haskell98') that are supported by some implementations, usually
-- in some special mode.

data Extension =
  -- | Enable a known extension
    EnableExtension KnownExtension

  -- | Disable a known extension
  | DisableExtension KnownExtension

  -- | An unknown extension, identified by the name of its @LANGUAGE@
  -- pragma.
  | UnknownExtension String
  deriving (Int -> Extension -> ShowS
[Extension] -> ShowS
Extension -> String
(Int -> Extension -> ShowS)
-> (Extension -> String)
-> ([Extension] -> ShowS)
-> Show Extension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Extension -> ShowS
showsPrec :: Int -> Extension -> ShowS
$cshow :: Extension -> String
show :: Extension -> String
$cshowList :: [Extension] -> ShowS
showList :: [Extension] -> ShowS
Show, ReadPrec [Extension]
ReadPrec Extension
Int -> ReadS Extension
ReadS [Extension]
(Int -> ReadS Extension)
-> ReadS [Extension]
-> ReadPrec Extension
-> ReadPrec [Extension]
-> Read Extension
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Extension
readsPrec :: Int -> ReadS Extension
$creadList :: ReadS [Extension]
readList :: ReadS [Extension]
$creadPrec :: ReadPrec Extension
readPrec :: ReadPrec Extension
$creadListPrec :: ReadPrec [Extension]
readListPrec :: ReadPrec [Extension]
Read, Extension -> Extension -> Bool
(Extension -> Extension -> Bool)
-> (Extension -> Extension -> Bool) -> Eq Extension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Extension -> Extension -> Bool
== :: Extension -> Extension -> Bool
$c/= :: Extension -> Extension -> Bool
/= :: Extension -> Extension -> Bool
Eq, Eq Extension
Eq Extension =>
(Extension -> Extension -> Ordering)
-> (Extension -> Extension -> Bool)
-> (Extension -> Extension -> Bool)
-> (Extension -> Extension -> Bool)
-> (Extension -> Extension -> Bool)
-> (Extension -> Extension -> Extension)
-> (Extension -> Extension -> Extension)
-> Ord Extension
Extension -> Extension -> Bool
Extension -> Extension -> Ordering
Extension -> Extension -> Extension
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Extension -> Extension -> Ordering
compare :: Extension -> Extension -> Ordering
$c< :: Extension -> Extension -> Bool
< :: Extension -> Extension -> Bool
$c<= :: Extension -> Extension -> Bool
<= :: Extension -> Extension -> Bool
$c> :: Extension -> Extension -> Bool
> :: Extension -> Extension -> Bool
$c>= :: Extension -> Extension -> Bool
>= :: Extension -> Extension -> Bool
$cmax :: Extension -> Extension -> Extension
max :: Extension -> Extension -> Extension
$cmin :: Extension -> Extension -> Extension
min :: Extension -> Extension -> Extension
Ord)


data KnownExtension =

  -- | [GHC &#xa7; 7.6.3.4] Allow overlapping class instances,
  -- provided there is a unique most specific instance for each use.
    OverlappingInstances

  -- | [GHC &#xa7; 7.6.3.3] Ignore structural rules guaranteeing the
  -- termination of class instance resolution.  Termination is
  -- guaranteed by a fixed-depth recursion stack, and compilation
  -- may fail if this depth is exceeded.
  | UndecidableInstances

  -- | [GHC &#xa7; 7.6.3.4] Implies 'OverlappingInstances'.  Allow the
  -- implementation to choose an instance even when it is possible
  -- that further instantiation of types will lead to a more specific
  -- instance being applicable.
  | IncoherentInstances

  -- | [GHC &#xa7; 7.6.3.5] Allow type signatures in instances.
  | InstanceSigs

  -- | [GHC &#xa7; 7.3.8] Deprecated in GHC.  Allows recursive
  -- bindings in @do@ blocks, using the @rec@ keyword.
  | DoRec

  -- | [GHC &#xa7; 7.3.8.2] Allows recursive bindings using @mdo@, a
  -- variant of @do@, and @rec@.
  | RecursiveDo

  -- | [GHC &#xa7; 7.3.9] Provide syntax for writing list
  -- comprehensions which iterate over several lists together, like
  -- the 'zipWith' family of functions.
  | ParallelListComp

  -- | [GHC &#xa7; 7.6.1.1] Allow multiple parameters in a type class.
  | MultiParamTypeClasses

  -- | [GHC &#xa7; 7.17] Enable the dreaded monomorphism restriction.
  | MonomorphismRestriction

  -- | [GHC &#xa7; 7.6.2] Allow a specification attached to a
  -- multi-parameter type class which indicates that some parameters
  -- are entirely determined by others. The implementation will check
  -- that this property holds for the declared instances, and will use
  -- this property to reduce ambiguity in instance resolution.
  | FunctionalDependencies

  -- | [GHC &#xa7; 7.8.5] Like 'RankNTypes' but does not allow a
  -- higher-rank type to itself appear on the left of a function
  -- arrow.
  | Rank2Types

  -- | [GHC &#xa7; 7.8.5] Allow a universally-quantified type to occur on
  -- the left of a function arrow.
  | RankNTypes

  -- | [GHC &#xa7; 7.8.5] Allow data constructors to have polymorphic
  -- arguments.  Unlike 'RankNTypes', does not allow this for ordinary
  -- functions.
  | PolymorphicComponents

  -- | [GHC &#xa7; 7.4.4] Allow existentially-quantified data constructors.
  | ExistentialQuantification

  -- | [GHC &#xa7; 7.8.7] Cause a type variable in a signature, which has an
  -- explicit @forall@ quantifier, to scope over the definition of the
  -- accompanying value declaration.
  | ScopedTypeVariables

  -- | Deprecated, use 'ScopedTypeVariables' instead.
  | PatternSignatures

  -- | [GHC &#xa7; 7.8.3] Enable implicit function parameters with dynamic
  -- scope.
  | ImplicitParams

  -- | [GHC &#xa7; 7.8.2] Relax some restrictions on the form of the context
  -- of a type signature.
  | FlexibleContexts

  -- | [GHC &#xa7; 7.6.3.2] Relax some restrictions on the form of the
  -- context of an instance declaration.
  | FlexibleInstances

  -- | [GHC &#xa7; 7.4.1] Allow data type declarations with no constructors.
  | EmptyDataDecls

  -- | [GHC &#xa7; 4.10.3] Run the C preprocessor on Haskell source code.
  | CPP

  -- | [GHC &#xa7; 7.8.4] Allow an explicit kind signature giving the kind of
  -- types over which a type variable ranges.
  | KindSignatures

  -- | [GHC &#xa7; 7.11] Enable a form of pattern which forces evaluation
  -- before an attempted match, and a form of strict @let@/@where@
  -- binding.
  | BangPatterns

  -- | [GHC &#xa7; 7.6.3.1] Allow type synonyms in instance heads.
  | TypeSynonymInstances

  -- | [GHC &#xa7; 7.9] Enable Template Haskell, a system for compile-time
  -- metaprogramming.
  | TemplateHaskell

  -- | [GHC &#xa7; 8] Enable the Foreign Function Interface.  In GHC,
  -- implements the standard Haskell 98 Foreign Function Interface
  -- Addendum, plus some GHC-specific extensions.
  | ForeignFunctionInterface

  -- | [GHC &#xa7; 7.10] Enable arrow notation.
  | Arrows

  -- | [GHC &#xa7; 7.16] Enable generic type classes, with default instances
  -- defined in terms of the algebraic structure of a type.
  | Generics

  -- | [GHC &#xa7; 7.3.11] Enable the implicit importing of the module
  -- @Prelude@.  When disabled, when desugaring certain built-in syntax
  -- into ordinary identifiers, use whatever is in scope rather than the
  -- @Prelude@ -- version.
  | ImplicitPrelude

  -- | [GHC &#xa7; 7.3.15] Enable syntax for implicitly binding local names
  -- corresponding to the field names of a record.  Puns bind specific
  -- names, unlike 'RecordWildCards'.
  | NamedFieldPuns

  -- | [GHC &#xa7; 7.3.5] Enable a form of guard which matches a pattern and
  -- binds variables.
  | PatternGuards

  -- | [GHC &#xa7; 7.5.4] Allow a type declared with @newtype@ to use
  -- @deriving@ for any class with an instance for the underlying type.
  | GeneralizedNewtypeDeriving

  -- | [GHC &#xa7; 9.6.10] Allow use of any typeclass in deriving clauses.
  | DeriveAnyClass

  -- | [Hugs &#xa7; 7.1] Enable the \"Trex\" extensible records system.
  | ExtensibleRecords

  -- | [Hugs &#xa7; 7.2] Enable type synonyms which are transparent in
  -- some definitions and opaque elsewhere, as a way of implementing
  -- abstract datatypes.
  | RestrictedTypeSynonyms

  -- | [Hugs &#xa7; 7.3] Enable an alternate syntax for string literals,
  -- with string templating.
  | HereDocuments

  -- | [GHC &#xa7; 7.3.2] Allow the character @#@ as a postfix modifier on
  -- identifiers.  Also enables literal syntax for unboxed values.
  | MagicHash

  -- | Binary integer literals
  | BinaryLiterals

  -- | [GHC &#xa7; 7.7] Allow data types and type synonyms which are
  -- indexed by types, i.e. ad-hoc polymorphism for types.
  | TypeFamilies

  -- | [GHC &#xa7; 7.5.2] Allow a standalone declaration which invokes the
  -- type class @deriving@ mechanism.
  | StandaloneDeriving

  -- | [GHC &#xa7; 7.3.1] Allow certain Unicode characters to stand for
  -- certain ASCII character sequences, e.g. keywords and punctuation.
  | UnicodeSyntax

  -- | [GHC &#xa7; 8.1.1] Allow the use of unboxed types as foreign types,
  -- e.g. in @foreign import@ and @foreign export@.
  | UnliftedFFITypes

  -- | [GHC &#xa7; 7.4.3] Defer validity checking of types until after
  -- expanding type synonyms, relaxing the constraints on how synonyms
  -- may be used.
  | LiberalTypeSynonyms

  -- | [GHC &#xa7; 7.4.2] Allow the name of a type constructor, type class,
  -- or type variable to be an infix operator.
  | TypeOperators

  -- | [GHC &#xa7; 7.26.5] Parallel arrays for Data Parallel Haskell.
  | ParallelArrays

  -- | [GHC &#xa7; 7.3.16] Enable syntax for implicitly binding local names
  -- corresponding to the field names of a record.  A wildcard binds
  -- all unmentioned names, unlike 'NamedFieldPuns'.
  | RecordWildCards

  -- | Deprecated, use 'NamedFieldPuns' instead.
  | RecordPuns

  -- | [GHC &#xa7; 7.3.14] Allow a record field name to be disambiguated
  -- by the type of the record it's in.
  | DisambiguateRecordFields

  -- | [GHC &#xa7; 7.6.4] Enable overloading of string literals using a
  -- type class, much like integer literals.
  | OverloadedStrings

  -- | [GHC &#xa7; 7.4.6] Enable generalized algebraic data types, in
  -- which type variables may be instantiated on a per-constructor
  -- basis. Implies GADTSyntax.
  | GADTs

{- GADTSyntax (the extension name) not yet supported by HSE

  -- | Enable GADT syntax for declaring ordinary algebraic datatypes.
  | GADTSyntax

-}

  -- | [GHC &#xa7; 7.17.2] Make pattern bindings monomorphic.
  | MonoPatBinds

  -- | [GHC &#xa7; 7.8.8] Relax the requirements on mutually-recursive
  -- polymorphic functions.
  | RelaxedPolyRec

  -- | [GHC &#xa7; 2.4.5] Allow default instantiation of polymorphic
  -- types in more situations.
  | ExtendedDefaultRules

  -- | [GHC &#xa7; 7.2.2] Enable unboxed tuples.
  | UnboxedTuples

  -- | [GHC &#xa7; 7.5.3] Enable @deriving@ for classes
  -- @Data.Typeable.Typeable@ and @Data.Generics.Data@.
  | DeriveDataTypeable

  -- | [GHC &#xa7; 7.6.1.3] Allow a class method's type to place
  -- additional constraints on a class type variable.
  | ConstrainedClassMethods

  -- | [GHC &#xa7; 7.3.18] Allow imports to be qualified by the package
  -- name the module is intended to be imported from, e.g.
  --
  -- > import "network" Network.Socket
  | PackageImports

  | LambdaCase

  -- | [GHC &#xa7; 7.3.20] Allow case expressions with no alternatives.
  | EmptyCase

  -- | [GHC &#xa7; 7.8.6] Deprecated in GHC 6.12 and will be removed in
  -- GHC 7.  Allow a type variable to be instantiated at a
  -- polymorphic type.
  | ImpredicativeTypes

  -- | [GHC &#xa7; 7.3.3] Change the syntax for qualified infix
  -- operators.
  | NewQualifiedOperators

  -- | [GHC &#xa7; 7.3.12] Relax the interpretation of left operator
  -- sections to allow unary postfix operators.
  | PostfixOperators

  -- | [GHC &#xa7; 7.9.5] Enable quasi-quotation, a mechanism for defining
  -- new concrete syntax for expressions and patterns.
  | QuasiQuotes

  -- | [GHC &#xa7; 7.3.10] Enable generalized list comprehensions,
  -- supporting operations such as sorting and grouping.
  | TransformListComp

  -- | [GHC &#xa7; 7.3.6] Enable view patterns, which match a value by
  -- applying a function and matching on the result.
  | ViewPatterns

  -- | Allow concrete XML syntax to be used in expressions and patterns,
  -- as per the Haskell Server Pages extension language:
  -- <http://www.haskell.org/haskellwiki/HSP>. The ideas behind it are
  -- discussed in the paper \"Haskell Server Pages through Dynamic Loading\"
  -- by Niklas Broberg, from Haskell Workshop '05.
  | XmlSyntax

  -- | Allow regular pattern matching over lists, as discussed in the
  -- paper \"Regular Expression Patterns\" by Niklas Broberg, Andreas Farre
  -- and Josef Svenningsson, from ICFP '04.
  | RegularPatterns

  -- | Enables the use of tuple sections, e.g. @(, True)@ desugars into
  -- @\x -> (x, True)@.
  | TupleSections

  -- | Allows GHC primops, written in C--, to be imported into a Haskell
  -- file.
  | GHCForeignImportPrim

  -- | Support for patterns of the form @n + k@, where @k@ is an
  -- integer literal.
  | NPlusKPatterns

  -- | Improve the layout rule when @if@ expressions are used in a @do@
  -- block.
  | DoAndIfThenElse

  -- | Makes much of the Haskell sugar be desugared into calls to the
  -- function with a particular name that is in scope.
  | RebindableSyntax

  -- | Make @forall@ a keyword in types, which can be used to give the
  -- generalisation explicitly.
  | ExplicitForAll

  -- | Allow contexts to be put on datatypes, e.g. the @Eq a@ in
  -- @data Eq a => Set a = NilSet | ConsSet a (Set a)@.
  | DatatypeContexts

  -- | Local (@let@ and @where@) bindings are monomorphic.
  | MonoLocalBinds

  -- | Enable @deriving@ for the @Data.Functor.Functor@ class.
  | DeriveFunctor

  -- | [GHC &#xa7; 7.5.3] Enable @deriving@ for the @Generic@ and @Generic1@ classes.
  | DeriveGeneric

  -- | Enable @deriving@ for the @Data.Traversable.Traversable@ class.
  | DeriveTraversable

  -- | Enable @deriving@ for the @Data.Foldable.Foldable@ class.
  | DeriveFoldable

  -- | Enable non-decreasing indentation for 'do' blocks.
  | NondecreasingIndentation

  -- | [GHC &#xa7; 8.1.4] Enable interruptible FFI.
  | InterruptibleFFI

  -- | [GHC &#xa7; 8.1.5] Enable the 'capi' calling convention in the
  -- foreign function interface.
  | CApiFFI

  -- | GHCJS FFI extension with convenient import patterns,
  -- asynchronous FFI and a JSVal FFI type
  | JavaScriptFFI

  -- | [GHC &#xa7; 7.3.27] Enable explicit namespaces in import/export.
  | ExplicitNamespaces

  | DataKinds

  | PolyKinds

  -- | [GHC &#xa7; 7.3.16] Enable the multi-way if-expressions
  -- extension to accept conditional expressions with multiple branches.
  | MultiWayIf

  -- | [GHC &#xa7; 7.20.3] Allow imports to be qualified with a safe
  -- keyword that requires the imported module be trusted as according
  -- to the Safe Haskell definition of trust.
  --
  -- > import safe Network.Socket
  | SafeImports

  -- | [GHC &#xa7; 7.20] Compile a module in the Safe, Safe Haskell
  -- mode -- a restricted form of the Haskell language to ensure
  -- type safety.
  | Safe

  -- | [GHC &#xa7; 7.20] Compile a module in the Trustworthy, Safe
  -- Haskell mode -- no restrictions apply but the module is marked
  -- as trusted as long as the package the module resides in is
  -- trusted.
  | Trustworthy

  -- | [GHC &#xa7; 7.6.1.4] Allow default signatures in class
  -- definitions. They apply to default methods implemented in this
  -- class.
  | DefaultSignatures


-- ConstraintKinds not generally supported by HSE. This flag makes RCategory2.hs
-- pass testing though.

  -- | [GHC &#xa7; 7.40] Allow type class/implicit parameter/equality
  -- constraints to be used as types with the special kind Constraint.
  -- Also generalise the (ctxt => ty) syntax so that any type of kind
  -- Constraint can occur before the arrow.
  | ConstraintKinds

  -- | [GHC &#xa7; 7.25.3] Allow role annotations.
  | RoleAnnotations
  -- | [GHC &#xa7; 7.3.8] Enable giving names to parametrized pattern
  -- schemes
  | PatternSynonyms

  -- | [GHC &#xa7; 7.15] Allow partial specified type signatures.
  -- Note that this extension does not affect parsing. It only affects whether the
  -- program is able to be run with partial signatures.
  | PartialTypeSignatures

  -- | [GHC &#xa7; 7.15.1.2] This extension treats type variables which
  -- start with an underscore as wildcards. For example, `foo :: _x` is
  -- equivalent to `foo :: _`.
  | NamedWildCards

  | TypeApplications

  | TypeFamilyDependencies

  | OverloadedLabels

  -- | Allow multiple @deriving@ clauses, each optionally qualified with a
  -- /strategy/.
  | DerivingStrategies

  | UnboxedSums

  | TypeInType

  | Strict

  | StrictData

  -- | Enable deriving instances via types of the same runtime representation.
  -- Implies 'DerivingStrategies'.
  | DerivingVia

  | QuantifiedConstraints

  | BlockArguments

  deriving (Int -> KnownExtension -> ShowS
[KnownExtension] -> ShowS
KnownExtension -> String
(Int -> KnownExtension -> ShowS)
-> (KnownExtension -> String)
-> ([KnownExtension] -> ShowS)
-> Show KnownExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KnownExtension -> ShowS
showsPrec :: Int -> KnownExtension -> ShowS
$cshow :: KnownExtension -> String
show :: KnownExtension -> String
$cshowList :: [KnownExtension] -> ShowS
showList :: [KnownExtension] -> ShowS
Show, ReadPrec [KnownExtension]
ReadPrec KnownExtension
Int -> ReadS KnownExtension
ReadS [KnownExtension]
(Int -> ReadS KnownExtension)
-> ReadS [KnownExtension]
-> ReadPrec KnownExtension
-> ReadPrec [KnownExtension]
-> Read KnownExtension
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS KnownExtension
readsPrec :: Int -> ReadS KnownExtension
$creadList :: ReadS [KnownExtension]
readList :: ReadS [KnownExtension]
$creadPrec :: ReadPrec KnownExtension
readPrec :: ReadPrec KnownExtension
$creadListPrec :: ReadPrec [KnownExtension]
readListPrec :: ReadPrec [KnownExtension]
Read, KnownExtension -> KnownExtension -> Bool
(KnownExtension -> KnownExtension -> Bool)
-> (KnownExtension -> KnownExtension -> Bool) -> Eq KnownExtension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KnownExtension -> KnownExtension -> Bool
== :: KnownExtension -> KnownExtension -> Bool
$c/= :: KnownExtension -> KnownExtension -> Bool
/= :: KnownExtension -> KnownExtension -> Bool
Eq, Eq KnownExtension
Eq KnownExtension =>
(KnownExtension -> KnownExtension -> Ordering)
-> (KnownExtension -> KnownExtension -> Bool)
-> (KnownExtension -> KnownExtension -> Bool)
-> (KnownExtension -> KnownExtension -> Bool)
-> (KnownExtension -> KnownExtension -> Bool)
-> (KnownExtension -> KnownExtension -> KnownExtension)
-> (KnownExtension -> KnownExtension -> KnownExtension)
-> Ord KnownExtension
KnownExtension -> KnownExtension -> Bool
KnownExtension -> KnownExtension -> Ordering
KnownExtension -> KnownExtension -> KnownExtension
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: KnownExtension -> KnownExtension -> Ordering
compare :: KnownExtension -> KnownExtension -> Ordering
$c< :: KnownExtension -> KnownExtension -> Bool
< :: KnownExtension -> KnownExtension -> Bool
$c<= :: KnownExtension -> KnownExtension -> Bool
<= :: KnownExtension -> KnownExtension -> Bool
$c> :: KnownExtension -> KnownExtension -> Bool
> :: KnownExtension -> KnownExtension -> Bool
$c>= :: KnownExtension -> KnownExtension -> Bool
>= :: KnownExtension -> KnownExtension -> Bool
$cmax :: KnownExtension -> KnownExtension -> KnownExtension
max :: KnownExtension -> KnownExtension -> KnownExtension
$cmin :: KnownExtension -> KnownExtension -> KnownExtension
min :: KnownExtension -> KnownExtension -> KnownExtension
Ord, Int -> KnownExtension
KnownExtension -> Int
KnownExtension -> [KnownExtension]
KnownExtension -> KnownExtension
KnownExtension -> KnownExtension -> [KnownExtension]
KnownExtension
-> KnownExtension -> KnownExtension -> [KnownExtension]
(KnownExtension -> KnownExtension)
-> (KnownExtension -> KnownExtension)
-> (Int -> KnownExtension)
-> (KnownExtension -> Int)
-> (KnownExtension -> [KnownExtension])
-> (KnownExtension -> KnownExtension -> [KnownExtension])
-> (KnownExtension -> KnownExtension -> [KnownExtension])
-> (KnownExtension
    -> KnownExtension -> KnownExtension -> [KnownExtension])
-> Enum KnownExtension
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: KnownExtension -> KnownExtension
succ :: KnownExtension -> KnownExtension
$cpred :: KnownExtension -> KnownExtension
pred :: KnownExtension -> KnownExtension
$ctoEnum :: Int -> KnownExtension
toEnum :: Int -> KnownExtension
$cfromEnum :: KnownExtension -> Int
fromEnum :: KnownExtension -> Int
$cenumFrom :: KnownExtension -> [KnownExtension]
enumFrom :: KnownExtension -> [KnownExtension]
$cenumFromThen :: KnownExtension -> KnownExtension -> [KnownExtension]
enumFromThen :: KnownExtension -> KnownExtension -> [KnownExtension]
$cenumFromTo :: KnownExtension -> KnownExtension -> [KnownExtension]
enumFromTo :: KnownExtension -> KnownExtension -> [KnownExtension]
$cenumFromThenTo :: KnownExtension
-> KnownExtension -> KnownExtension -> [KnownExtension]
enumFromThenTo :: KnownExtension
-> KnownExtension -> KnownExtension -> [KnownExtension]
Enum, KnownExtension
KnownExtension -> KnownExtension -> Bounded KnownExtension
forall a. a -> a -> Bounded a
$cminBound :: KnownExtension
minBound :: KnownExtension
$cmaxBound :: KnownExtension
maxBound :: KnownExtension
Bounded, Typeable KnownExtension
Typeable KnownExtension =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> KnownExtension -> c KnownExtension)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c KnownExtension)
-> (KnownExtension -> Constr)
-> (KnownExtension -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c KnownExtension))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c KnownExtension))
-> ((forall b. Data b => b -> b)
    -> KnownExtension -> KnownExtension)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> KnownExtension -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> KnownExtension -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> KnownExtension -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> KnownExtension -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> KnownExtension -> m KnownExtension)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> KnownExtension -> m KnownExtension)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> KnownExtension -> m KnownExtension)
-> Data KnownExtension
KnownExtension -> Constr
KnownExtension -> DataType
(forall b. Data b => b -> b) -> KnownExtension -> KnownExtension
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> KnownExtension -> u
forall u. (forall d. Data d => d -> u) -> KnownExtension -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> KnownExtension -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> KnownExtension -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c KnownExtension
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> KnownExtension -> c KnownExtension
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c KnownExtension)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c KnownExtension)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> KnownExtension -> c KnownExtension
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> KnownExtension -> c KnownExtension
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c KnownExtension
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c KnownExtension
$ctoConstr :: KnownExtension -> Constr
toConstr :: KnownExtension -> Constr
$cdataTypeOf :: KnownExtension -> DataType
dataTypeOf :: KnownExtension -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c KnownExtension)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c KnownExtension)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c KnownExtension)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c KnownExtension)
$cgmapT :: (forall b. Data b => b -> b) -> KnownExtension -> KnownExtension
gmapT :: (forall b. Data b => b -> b) -> KnownExtension -> KnownExtension
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> KnownExtension -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> KnownExtension -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> KnownExtension -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> KnownExtension -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> KnownExtension -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> KnownExtension -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> KnownExtension -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> KnownExtension -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> KnownExtension -> m KnownExtension
Data, Typeable)

-- | Certain extensions imply other extensions, and this function
--   makes the implication explicit. This also handles deprecated
--   extensions, which imply their replacements.
--   The returned value is the transitive closure of implied
--   extensions.
{-impliesExts :: [Extension] -> [Extension]
impliesExts exts =
    let posExts = [ ke | EnableExtension  ke <- exts ]
        negExts = [ ke | DisableExtension ke <- exts ]

        implExts = impliesKnownExts posExts
     in
-}
impliesExts :: [KnownExtension] -> [KnownExtension]
impliesExts :: [KnownExtension] -> [KnownExtension]
impliesExts = [KnownExtension] -> [KnownExtension]
go
  where go :: [KnownExtension] -> [KnownExtension]
go [] = []
        go [KnownExtension]
es = let xs :: [KnownExtension]
xs = (KnownExtension -> [KnownExtension])
-> [KnownExtension] -> [KnownExtension]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap KnownExtension -> [KnownExtension]
implE [KnownExtension]
es
                    ys :: [KnownExtension]
ys = (KnownExtension -> Bool) -> [KnownExtension] -> [KnownExtension]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (KnownExtension -> Bool) -> KnownExtension -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (KnownExtension -> [KnownExtension] -> Bool)
-> [KnownExtension] -> KnownExtension -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip KnownExtension -> [KnownExtension] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem [KnownExtension]
es) [KnownExtension]
xs
                 in [KnownExtension]
es [KnownExtension] -> [KnownExtension] -> [KnownExtension]
forall a. [a] -> [a] -> [a]
++ [KnownExtension] -> [KnownExtension]
go [KnownExtension]
ys

        implE :: KnownExtension -> [KnownExtension]
implE KnownExtension
e = case KnownExtension
e of
                    KnownExtension
TypeFamilies        -> [KnownExtension
KindSignatures]
                    KnownExtension
ScopedTypeVariables -> [KnownExtension
TypeOperators, KnownExtension
ExplicitForAll]
                    KnownExtension
XmlSyntax           -> [KnownExtension
RegularPatterns]
                    KnownExtension
RegularPatterns     -> [KnownExtension
PatternGuards]
                    KnownExtension
RankNTypes          -> [KnownExtension
Rank2Types, KnownExtension
ExplicitForAll]
                    KnownExtension
Rank2Types          -> [KnownExtension
PolymorphicComponents, KnownExtension
ExplicitForAll]
                    KnownExtension
PolymorphicComponents   -> [KnownExtension
ExplicitForAll]
                    KnownExtension
LiberalTypeSynonyms -> [KnownExtension
ExplicitForAll]
                    KnownExtension
ExistentialQuantification -> [KnownExtension
ExplicitForAll]
                    KnownExtension
ImpredicativeTypes   -> [KnownExtension
ExplicitForAll]
                    KnownExtension
PolyKinds           -> [KnownExtension
KindSignatures]
                    KnownExtension
TypeFamilyDependencies -> [KnownExtension
TypeFamilies]
                    KnownExtension
TypeInType          -> [KnownExtension
PolyKinds, KnownExtension
DataKinds, KnownExtension
KindSignatures]
                    KnownExtension
TypeOperators       -> [KnownExtension
ExplicitNamespaces]
                    -- Deprecations
                    KnownExtension
RecordPuns          -> [KnownExtension
NamedFieldPuns]
                    KnownExtension
PatternSignatures   -> [KnownExtension
ScopedTypeVariables]
                    KnownExtension
DerivingVia         -> [KnownExtension
DerivingStrategies]
                    KnownExtension
_                   -> []

-- | The list of extensions enabled by
--   GHC's portmanteau -fglasgow-exts flag.
glasgowExts :: [Extension]
glasgowExts :: [Extension]
glasgowExts = (KnownExtension -> Extension) -> [KnownExtension] -> [Extension]
forall a b. (a -> b) -> [a] -> [b]
map KnownExtension -> Extension
EnableExtension [
      KnownExtension
ForeignFunctionInterface
    , KnownExtension
UnliftedFFITypes
    , KnownExtension
GADTs
    , KnownExtension
ImplicitParams
    , KnownExtension
ScopedTypeVariables
    , KnownExtension
UnboxedTuples
    , KnownExtension
TypeSynonymInstances
    , KnownExtension
StandaloneDeriving
    , KnownExtension
DeriveDataTypeable
    , KnownExtension
FlexibleContexts
    , KnownExtension
FlexibleInstances
    , KnownExtension
ConstrainedClassMethods
    , KnownExtension
MultiParamTypeClasses
    , KnownExtension
FunctionalDependencies
    , KnownExtension
MagicHash
    , KnownExtension
PolymorphicComponents
    , KnownExtension
ExistentialQuantification
    , KnownExtension
UnicodeSyntax
    , KnownExtension
PostfixOperators
    , KnownExtension
PatternGuards
    , KnownExtension
LiberalTypeSynonyms
    , KnownExtension
RankNTypes
    , KnownExtension
ImpredicativeTypes
    , KnownExtension
TypeOperators
    , KnownExtension
RecursiveDo
    , KnownExtension
ParallelListComp
    , KnownExtension
EmptyDataDecls
    , KnownExtension
KindSignatures
    , KnownExtension
GeneralizedNewtypeDeriving
    , KnownExtension
TypeFamilies
    ]

-- Not exported, just used locally in several places.
allLangDefault :: [KnownExtension]
allLangDefault :: [KnownExtension]
allLangDefault = [KnownExtension
MonomorphismRestriction, KnownExtension
MonoPatBinds, KnownExtension
ImplicitPrelude]

ghcDefault :: [Extension]
ghcDefault :: [Extension]
ghcDefault = (KnownExtension -> Extension) -> [KnownExtension] -> [Extension]
forall a b. (a -> b) -> [a] -> [b]
map KnownExtension -> Extension
EnableExtension (KnownExtension
NondecreasingIndentationKnownExtension -> [KnownExtension] -> [KnownExtension]
forall a. a -> [a] -> [a]
:[KnownExtension]
allLangDefault)

-- | List of all known extensions, both \"yes\" and \"no\" versions.
knownExtensions :: [Extension]
knownExtensions :: [Extension]
knownExtensions =
  [[Extension]] -> [Extension]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [KnownExtension -> Extension
EnableExtension KnownExtension
x, KnownExtension -> Extension
DisableExtension KnownExtension
x] | KnownExtension
x <- [KnownExtension
forall a. Bounded a => a
minBound..KnownExtension
forall a. Bounded a => a
maxBound] ]

-- | Extensions that have been deprecated, possibly paired with another
-- extension that replaces it.
--
deprecatedExtensions :: [(Extension, Maybe Extension)]
deprecatedExtensions :: [(Extension, Maybe Extension)]
deprecatedExtensions =
  [ (KnownExtension -> Extension
EnableExtension KnownExtension
RecordPuns, Extension -> Maybe Extension
forall a. a -> Maybe a
Just (KnownExtension -> Extension
EnableExtension KnownExtension
NamedFieldPuns))
  , (KnownExtension -> Extension
EnableExtension KnownExtension
PatternSignatures, Extension -> Maybe Extension
forall a. a -> Maybe a
Just (KnownExtension -> Extension
EnableExtension KnownExtension
ScopedTypeVariables))
  ]



-- | A clever version of read that returns an 'UnknownExtension'
--   if the string is not recognised.
classifyExtension :: String -> Extension
classifyExtension :: String -> Extension
classifyExtension String
string
  = case String -> Maybe KnownExtension
classifyKnownExtension String
string of
    Just KnownExtension
ext -> KnownExtension -> Extension
EnableExtension KnownExtension
ext
    Maybe KnownExtension
Nothing ->
        case String
string of
        Char
'N':Char
'o':String
string' ->
            case String -> Maybe KnownExtension
classifyKnownExtension String
string' of
            Just KnownExtension
ext -> KnownExtension -> Extension
DisableExtension KnownExtension
ext
            Maybe KnownExtension
Nothing -> String -> Extension
UnknownExtension String
string
        String
_ -> String -> Extension
UnknownExtension String
string


classifyKnownExtension :: String -> Maybe KnownExtension
classifyKnownExtension :: String -> Maybe KnownExtension
classifyKnownExtension String
"" = Maybe KnownExtension
forall a. Maybe a
Nothing
classifyKnownExtension string :: String
string@(Char
c : String
_)
  | (Char, Char) -> Char -> Bool
forall a. Ix a => (a, a) -> a -> Bool
inRange (Array Char [(String, KnownExtension)] -> (Char, Char)
forall i e. Array i e -> (i, i)
bounds Array Char [(String, KnownExtension)]
knownExtensionTable) Char
c
  = String -> [(String, KnownExtension)] -> Maybe KnownExtension
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
string (Array Char [(String, KnownExtension)]
knownExtensionTable Array Char [(String, KnownExtension)]
-> Char -> [(String, KnownExtension)]
forall i e. Ix i => Array i e -> i -> e
! Char
c)
  | Bool
otherwise = Maybe KnownExtension
forall a. Maybe a
Nothing

knownExtensionTable :: Array Char [(String, KnownExtension)]
knownExtensionTable :: Array Char [(String, KnownExtension)]
knownExtensionTable =
  ([(String, KnownExtension)]
 -> (String, KnownExtension) -> [(String, KnownExtension)])
-> [(String, KnownExtension)]
-> (Char, Char)
-> [(Char, (String, KnownExtension))]
-> Array Char [(String, KnownExtension)]
forall i e a.
Ix i =>
(e -> a -> e) -> e -> (i, i) -> [(i, a)] -> Array i e
accumArray (((String, KnownExtension)
 -> [(String, KnownExtension)] -> [(String, KnownExtension)])
-> [(String, KnownExtension)]
-> (String, KnownExtension)
-> [(String, KnownExtension)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (:)) [] (Char
'A', Char
'Z')
    [ (String -> Char
forall a. HasCallStack => [a] -> a
head String
str, (String
str, KnownExtension
extension))
    | KnownExtension
extension <- [Int -> KnownExtension
forall a. Enum a => Int -> a
toEnum Int
0 ..]
    , let str :: String
str = KnownExtension -> String
forall a. Show a => a -> String
show KnownExtension
extension ]

-- | Parse an enabled or disabled extension; returns
-- 'UnknownExtension' if the parse fails.
parseExtension :: String -> Extension
parseExtension :: String -> Extension
parseExtension String
str = Extension -> Maybe Extension -> Extension
forall a. a -> Maybe a -> a
fromMaybe (String -> Extension
UnknownExtension String
str) (Maybe Extension -> Extension) -> Maybe Extension -> Extension
forall a b. (a -> b) -> a -> b
$
      KnownExtension -> Extension
EnableExtension  (KnownExtension -> Extension)
-> Maybe KnownExtension -> Maybe Extension
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Maybe KnownExtension
forall a. Read a => String -> Maybe a
readMay String
str
  Maybe Extension -> Maybe Extension -> Maybe Extension
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> KnownExtension -> Extension
DisableExtension (KnownExtension -> Extension)
-> Maybe KnownExtension -> Maybe Extension
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> Maybe KnownExtension
forall a. Read a => String -> Maybe a
readMay (String -> Maybe KnownExtension)
-> Maybe String -> Maybe KnownExtension
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Maybe String
dropNo String
str)
  where
    dropNo :: String -> Maybe String
dropNo (Char
'N':Char
'o':String
rest) = String -> Maybe String
forall a. a -> Maybe a
Just String
rest
    dropNo String
_              = Maybe String
forall a. Maybe a
Nothing

-- | Pretty print an extension. Disabled extensions are prefixed with
-- \'No\'.
prettyExtension :: Extension -> String
prettyExtension :: Extension -> String
prettyExtension (EnableExtension  KnownExtension
ext) = KnownExtension -> String
forall a. Show a => a -> String
show KnownExtension
ext
prettyExtension (DisableExtension KnownExtension
ext) = String
"No" String -> ShowS
forall a. [a] -> [a] -> [a]
++ KnownExtension -> String
forall a. Show a => a -> String
show KnownExtension
ext
prettyExtension (UnknownExtension String
str) = String
str

readMay :: Read a => String -> Maybe a
readMay :: forall a. Read a => String -> Maybe a
readMay String
s = case [a
x | (a
x,String
t) <- ReadS a
forall a. Read a => ReadS a
reads String
s, (String
"",String
"") <- ReadS String
lex String
t] of
                [a
x] -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
                [a]
_ -> Maybe a
forall a. Maybe a
Nothing

{-------------------------------------------
 -- Transform a 'Language', and possibly a modifying set of'Extension's, into a list
 -- of 'KnownExtension's, to be interpreted as modifying the language you get
 -- when all known extensions are disabled.
 -- Extensions are interpreted in a right-biased fashion, so the last instance
 -- of an occurence of 'EnableExtension' or 'DisableExtension' for a given
 -- 'KnownExtension' takes precedence.
 -------------------------------------------}

toExtensionList :: Language -> [Extension] -> [KnownExtension]
toExtensionList :: Language -> [Extension] -> [KnownExtension]
toExtensionList Language
lang [Extension]
exts' =
    let langKes :: [KnownExtension]
langKes = case Language
lang of
                    Language
Haskell98 -> KnownExtension
NPlusKPatternsKnownExtension -> [KnownExtension] -> [KnownExtension]
forall a. a -> [a] -> [a]
:[KnownExtension]
allLangDefault
                    Language
Haskell2010 -> [KnownExtension
DoAndIfThenElse
                                   , KnownExtension
PatternGuards
                                   , KnownExtension
ForeignFunctionInterface
                                   , KnownExtension
EmptyDataDecls
                                   ] [KnownExtension] -> [KnownExtension] -> [KnownExtension]
forall a. [a] -> [a] -> [a]
++ [KnownExtension]
allLangDefault
                    Language
HaskellAllDisabled -> []
                    UnknownLanguage String
s ->
                        String -> [KnownExtension]
forall a. HasCallStack => String -> a
error (String -> [KnownExtension]) -> String -> [KnownExtension]
forall a b. (a -> b) -> a -> b
$ String
"toExtensionList: Unknown language " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s
{-
        addExts = [ ke | EnableExtension  ke <- exts ]
        remExts = [ ke | DisableExtension ke <- exts ]
     in impliesExts $ nub $ (langKes ++ addExts) \\ remExts
-}
  in [KnownExtension] -> [KnownExtension]
impliesExts ([KnownExtension] -> [KnownExtension])
-> [KnownExtension] -> [KnownExtension]
forall a b. (a -> b) -> a -> b
$ [KnownExtension] -> [KnownExtension]
forall a. Eq a => [a] -> [a]
nub ([KnownExtension] -> [KnownExtension])
-> [KnownExtension] -> [KnownExtension]
forall a b. (a -> b) -> a -> b
$ [KnownExtension] -> [Extension] -> [KnownExtension]
go [KnownExtension]
langKes [Extension]
exts'
    where go :: [KnownExtension] -> [Extension] -> [KnownExtension]
          go :: [KnownExtension] -> [Extension] -> [KnownExtension]
go [KnownExtension]
acc [] = [KnownExtension]
acc
          go [KnownExtension]
acc (DisableExtension KnownExtension
x : [Extension]
exts) = [KnownExtension] -> [Extension] -> [KnownExtension]
go ((KnownExtension -> Bool) -> [KnownExtension] -> [KnownExtension]
forall a. (a -> Bool) -> [a] -> [a]
filter (KnownExtension -> KnownExtension -> Bool
forall a. Eq a => a -> a -> Bool
/= KnownExtension
x) [KnownExtension]
acc) [Extension]
exts
          go [KnownExtension]
acc (EnableExtension  KnownExtension
x : [Extension]
exts) = [KnownExtension] -> [Extension] -> [KnownExtension]
go (KnownExtension
x KnownExtension -> [KnownExtension] -> [KnownExtension]
forall a. a -> [a] -> [a]
: [KnownExtension]
acc)           [Extension]
exts
          -- We just throw away UnknownExtensions
          go [KnownExtension]
acc (Extension
_ : [Extension]
exts) = [KnownExtension] -> [Extension] -> [KnownExtension]
go [KnownExtension]
acc [Extension]
exts