diff options
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/ghc-boot/GHC/Lexeme.hs | 32 | ||||
-rw-r--r-- | libraries/ghc-boot/GHC/PackageDb.hs (renamed from libraries/bin-package-db/GHC/PackageDb.hs) | 0 | ||||
-rw-r--r-- | libraries/ghc-boot/LICENSE (renamed from libraries/bin-package-db/LICENSE) | 0 | ||||
-rw-r--r-- | libraries/ghc-boot/ghc-boot.cabal (renamed from libraries/bin-package-db/bin-package-db.cabal) | 21 | ||||
-rw-r--r-- | libraries/template-haskell/Language/Haskell/TH.hs | 1 | ||||
-rw-r--r-- | libraries/template-haskell/Language/Haskell/TH/Syntax.hs | 69 | ||||
-rw-r--r-- | libraries/template-haskell/changelog.md | 8 | ||||
-rw-r--r-- | libraries/template-haskell/template-haskell.cabal | 1 |
8 files changed, 109 insertions, 23 deletions
diff --git a/libraries/ghc-boot/GHC/Lexeme.hs b/libraries/ghc-boot/GHC/Lexeme.hs new file mode 100644 index 0000000000..677c9a65e6 --- /dev/null +++ b/libraries/ghc-boot/GHC/Lexeme.hs @@ -0,0 +1,32 @@ +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Lexeme +-- Copyright : (c) The GHC Team +-- +-- Maintainer : ghc-devs@haskell.org +-- Portability : portable +-- +-- Functions to evaluate whether or not a string is a valid identifier. +-- +module GHC.Lexeme ( + -- * Lexical characteristics of Haskell names + startsVarSym, startsVarId, startsConSym, startsConId, + startsVarSymASCII, isVarSymChar + ) where + +import Data.Char + +startsVarSym, startsVarId, startsConSym, startsConId :: Char -> Bool +startsVarSym c = startsVarSymASCII c || (ord c > 0x7f && isSymbol c) -- Infix Ids +startsConSym c = c == ':' -- Infix data constructors +startsVarId c = c == '_' || case generalCategory c of -- Ordinary Ids + LowercaseLetter -> True + OtherLetter -> True -- See #1103 + _ -> False +startsConId c = isUpper c || c == '(' -- Ordinary type constructors and data constructors + +startsVarSymASCII :: Char -> Bool +startsVarSymASCII c = c `elem` "!#$%&*+./<=>?@\\^|~-" + +isVarSymChar :: Char -> Bool +isVarSymChar c = c == ':' || startsVarSym c diff --git a/libraries/bin-package-db/GHC/PackageDb.hs b/libraries/ghc-boot/GHC/PackageDb.hs index 672b7ebbe3..672b7ebbe3 100644 --- a/libraries/bin-package-db/GHC/PackageDb.hs +++ b/libraries/ghc-boot/GHC/PackageDb.hs diff --git a/libraries/bin-package-db/LICENSE b/libraries/ghc-boot/LICENSE index b5059b71f6..b5059b71f6 100644 --- a/libraries/bin-package-db/LICENSE +++ b/libraries/ghc-boot/LICENSE diff --git a/libraries/bin-package-db/bin-package-db.cabal b/libraries/ghc-boot/ghc-boot.cabal index a54fe16449..98929b7f83 100644 --- a/libraries/bin-package-db/bin-package-db.cabal +++ b/libraries/ghc-boot/ghc-boot.cabal @@ -1,17 +1,17 @@ -name: bin-package-db +name: ghc-boot version: 0.0.0.0 license: BSD3 maintainer: ghc-devs@haskell.org bug-reports: glasgow-haskell-bugs@haskell.org -synopsis: The GHC compiler's view of the GHC package database format -description: This library is shared between GHC and ghc-pkg and is used by - GHC to read package databases. +synopsis: Shared functionality between GHC and its boot libraries +description: This library is shared between GHC, ghc-pkg, and other boot + libraries. . - It only deals with the subset of the package database that the - compiler cares about: modules paths etc and not package - metadata like description, authors etc. It is thus not a - library interface to ghc-pkg and is *not* suitable for - modifying GHC package databases. + A note about "GHC.PackageDb": it only deals with the subset of + the package database that the compiler cares about: modules + paths etc and not package metadata like description, authors + etc. It is thus not a library interface to ghc-pkg and is *not* + suitable for modifying GHC package databases. . The package database format and this library are constructed in such a way that while ghc-pkg depends on Cabal, the GHC library @@ -22,7 +22,7 @@ build-type: Simple source-repository head type: git location: http://git.haskell.org/ghc.git - subdir: libraries/bin-package-db + subdir: libraries/ghc-boot Library default-language: Haskell2010 @@ -34,6 +34,7 @@ Library TypeSynonymInstances exposed-modules: + GHC.Lexeme GHC.PackageDb build-depends: base >= 4 && < 5, diff --git a/libraries/template-haskell/Language/Haskell/TH.hs b/libraries/template-haskell/Language/Haskell/TH.hs index bce8bf5ddb..49038816e7 100644 --- a/libraries/template-haskell/Language/Haskell/TH.hs +++ b/libraries/template-haskell/Language/Haskell/TH.hs @@ -51,6 +51,7 @@ module Language.Haskell.TH( nameBase, -- :: Name -> String nameModule, -- :: Name -> Maybe String namePackage, -- :: Name -> Maybe String + nameSpace, -- :: Name -> Maybe NameSpace -- ** Built-in names tupleTypeName, tupleDataName, -- Int -> Name unboxedTupleTypeName, unboxedTupleDataName, -- :: Int -> Name diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs index b64dfffb93..97c379d407 100644 --- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs +++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs @@ -38,6 +38,7 @@ import Data.Int import Data.Word import Data.Ratio import GHC.Generics ( Generic ) +import GHC.Lexeme ( startsVarSym, startsVarId ) #ifdef HAS_NATURAL import Numeric.Natural @@ -645,10 +646,10 @@ dataToQa mkCon mkLit appCon antiQ t = Nothing -> case constrRep constr of AlgConstr _ -> - appCon (mkCon conName) conArgs + appCon (mkCon funOrConName) conArgs where - conName :: Name - conName = + funOrConName :: Name + funOrConName = case showConstr constr of "(:)" -> Name (mkOccName ":") (NameG DataName @@ -662,13 +663,23 @@ dataToQa mkCon mkLit appCon antiQ t = (NameG DataName (mkPkgName "ghc-prim") (mkModName "GHC.Tuple")) - con -> mkNameG_d (tyConPackage tycon) - (tyConModule tycon) - con + -- It is possible for a Data instance to be defined such + -- that toConstr uses a Constr defined using a function, + -- not a data constructor. In such a case, we must take + -- care to build the Name using mkNameG_v (for values), + -- not mkNameG_d (for data constructors). + -- See Trac #10796. + fun@(x:_) | startsVarSym x || startsVarId x + -> mkNameG_v tyconPkg tyconMod fun + con -> mkNameG_d tyconPkg tyconMod con where tycon :: TyCon tycon = (typeRepTyCon . typeOf) t + tyconPkg, tyconMod :: String + tyconPkg = tyConPackage tycon + tyconMod = tyConModule tycon + conArgs :: [Q q] conArgs = gmapQ (dataToQa mkCon mkLit appCon antiQ) t IntConstr n -> @@ -691,8 +702,17 @@ dataToExpQ :: Data a => (forall b . Data b => b -> Maybe (Q Exp)) -> a -> Q Exp -dataToExpQ = dataToQa conE litE (foldl appE) - where conE s = return (ConE s) +dataToExpQ = dataToQa varOrConE litE (foldl appE) + where + -- Make sure that VarE is used if the Constr value relies on a + -- function underneath the surface (instead of a constructor). + -- See Trac #10796. + varOrConE s = + case nameSpace s of + Just VarName -> return (VarE s) + Just DataName -> return (ConE s) + _ -> fail $ "Can't construct an expression from name " + ++ showName s appE x y = do { a <- x; b <- y; return (AppE a b)} litE c = return (LitE c) @@ -710,8 +730,13 @@ dataToPatQ :: Data a -> Q Pat dataToPatQ = dataToQa id litP conP where litP l = return (LitP l) - conP n ps = do ps' <- sequence ps - return (ConP n ps') + conP n ps = + case nameSpace n of + Just DataName -> do + ps' <- sequence ps + return (ConP n ps') + _ -> fail $ "Can't construct a pattern from name " + ++ showName n ----------------------------------------------------- -- Names and uniques @@ -855,13 +880,13 @@ data NameFlavour -- An original name (occurrences only, not binders) -- Need the namespace too to be sure which -- thing we are naming - deriving ( Typeable, Data, Eq, Ord, Generic ) + deriving ( Typeable, Data, Eq, Ord, Show, Generic ) data NameSpace = VarName -- ^ Variables | DataName -- ^ Data constructors | TcClsName -- ^ Type constructors and classes; Haskell has them -- in the same name space for now. - deriving( Eq, Ord, Data, Typeable, Generic ) + deriving( Eq, Ord, Show, Data, Typeable, Generic ) type Uniq = Int @@ -907,6 +932,26 @@ namePackage :: Name -> Maybe String namePackage (Name _ (NameG _ p _)) = Just (pkgString p) namePackage _ = Nothing +-- | Returns whether a name represents an occurrence of a top-level variable +-- ('VarName'), data constructor ('DataName'), type constructor, or type class +-- ('TcClsName'). If we can't be sure, it returns 'Nothing'. +-- +-- ==== __Examples__ +-- +-- >>> nameSpace 'Prelude.id +-- Just VarName +-- >>> nameSpace (mkName "id") +-- Nothing -- only works for top-level variable names +-- >>> nameSpace 'Data.Maybe.Just +-- Just DataName +-- >>> nameSpace ''Data.Maybe.Maybe +-- Just TcClsName +-- >>> nameSpace ''Data.Ord.Ord +-- Just TcClsName +nameSpace :: Name -> Maybe NameSpace +nameSpace (Name _ (NameG ns _ _)) = Just ns +nameSpace _ = Nothing + {- | Generate a capturable name. Occurrences of such names will be resolved according to the Haskell scoping rules at the occurrence diff --git a/libraries/template-haskell/changelog.md b/libraries/template-haskell/changelog.md index fb701abf47..e4edf63f42 100644 --- a/libraries/template-haskell/changelog.md +++ b/libraries/template-haskell/changelog.md @@ -10,7 +10,13 @@ according to the fixities of the operators. The `ParensT` constructor can be used to explicitly group expressions. - * Add `namePackage` + * Add `namePackage` and `nameSpace` + + * Make `dataToQa` and `dataToExpQ` able to handle `Data` instances whose + `toConstr` implementation relies on a function instead of a data + constructor (#10796) + + * Add `Show` instances for `NameFlavour` and `NameSpace` * TODO: document API changes and important bugfixes diff --git a/libraries/template-haskell/template-haskell.cabal b/libraries/template-haskell/template-haskell.cabal index 4bfd1a96a7..dd31604e95 100644 --- a/libraries/template-haskell/template-haskell.cabal +++ b/libraries/template-haskell/template-haskell.cabal @@ -48,6 +48,7 @@ Library build-depends: base >= 4.6 && < 4.9, + ghc-boot, pretty == 1.1.* -- We need to set the package key to template-haskell (without a |