Teo Camarasu pushed to branch wip/abstract-q at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/Tc/Gen/Splice.hs
    ... ... @@ -1139,6 +1139,7 @@ convertAnnotationWrapper fhv = do
    1139 1139
     ************************************************************************
    
    1140 1140
     -}
    
    1141 1141
     
    
    1142
    +-- TODO: rename
    
    1142 1143
     runQuasi :: TH.Q a -> TcM a
    
    1143 1144
     runQuasi (TH.Q act) = unliftIOEnv $ \runInIO -> liftIO $ act (metaHandlersTcM runInIO)
    
    1144 1145
     
    
    ... ... @@ -1467,7 +1468,7 @@ when showing an error message.
    1467 1468
     To call runQ in the Tc monad, we need to make TcM an instance of Quasi:
    
    1468 1469
     -}
    
    1469 1470
     
    
    1470
    -report :: Bool -> [Char] -> TcM ()
    
    1471
    +report :: Bool -> String -> TcM ()
    
    1471 1472
     report True msg  = seqList msg $ addErr        $ TcRnTHError $ ReportCustomQuasiError True  msg
    
    1472 1473
     report False msg = seqList msg $ addDiagnostic $ TcRnTHError $ ReportCustomQuasiError False msg
    
    1473 1474
     
    
    ... ... @@ -1559,7 +1560,8 @@ location = do { m <- getModule
    1559 1560
     
    
    1560 1561
     metaHandlersTcM :: (forall x. TcM x -> IO x) -> TH.MetaHandlers IO
    
    1561 1562
     metaHandlersTcM runInIO = TH.MetaHandlers {
    
    1562
    -    mFail = \s -> runInIO $ fail s
    
    1563
    +    -- We are careful to use the TcM instance not the one for IO, since that would lead to a different error.
    
    1564
    +    mFail = \s -> runInIO $ fail @TcM s
    
    1563 1565
         , mNewName = \s -> runInIO $ do { u <- newUnique
    
    1564 1566
                           ; let i = toInteger (getKey u)
    
    1565 1567
                           ; return (TH.mkNameU s i) }
    
    ... ... @@ -1578,16 +1580,17 @@ metaHandlersTcM runInIO = TH.MetaHandlers {
    1578 1580
         , mReifyRoles       = runInIO . reifyRoles
    
    1579 1581
         , mReifyAnnotations = runInIO . reifyAnnotations
    
    1580 1582
         , mReifyModule      = runInIO . reifyModule
    
    1581
    -    , mReifyConStrictness = \nm -> runInIO $ do { nm' <- lookupThName nm
    
    1583
    +    , mReifyConStrictness = \nm -> runInIO $ do
    
    1584
    +                                      { nm' <- lookupThName nm
    
    1582 1585
                                           ; dc  <- tcLookupDataCon nm'
    
    1583 1586
                                           ; let bangs = dataConImplBangs dc
    
    1584 1587
                                           ; return (map reifyDecidedStrictness bangs) }
    
    1585 1588
     
    
    1586
    -    --       -- For qRecover, discard error messages if
    
    1587
    -    --       -- the recovery action is chosen.  Otherwise
    
    1588
    -    --       -- we'll only fail higher up.
    
    1589
    -    --       -- NB: extremely subtle!!! TODO: write up note
    
    1590
    -    --       -- tryTcDiscardingErrs manipulates the reader env so we need to be careful we don't sneak in the outside env
    
    1589
    +          -- For qRecover, discard error messages if
    
    1590
    +          -- the recovery action is chosen.  Otherwise
    
    1591
    +          -- we'll only fail higher up.
    
    1592
    +          -- NB: extremely subtle!!! TODO: write up note
    
    1593
    +          -- tryTcDiscardingErrs manipulates the reader env so we need to be careful we don't sneak in the outside env
    
    1591 1594
         , mRecover = \recover main -> runInIO $ tryTcDiscardingErrs (runQuasi recover) (runQuasi main)
    
    1592 1595
     
    
    1593 1596
         , mGetPackageRoot = runInIO $ do
    

  • libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
    ... ... @@ -1074,7 +1074,7 @@ withDecDoc :: String -> Q Dec -> Q Dec
    1074 1074
     withDecDoc doc dec = do
    
    1075 1075
       dec' <- dec
    
    1076 1076
       case doc_loc dec' of
    
    1077
    -    Just loc -> qAddModFinalizer $ qPutDoc loc doc
    
    1077
    +    Just loc -> addModFinalizer $ putDoc loc doc
    
    1078 1078
         Nothing  -> pure ()
    
    1079 1079
       pure dec'
    
    1080 1080
       where
    
    ... ... @@ -1123,7 +1123,7 @@ funD_doc :: Name -> [Q Clause]
    1123 1123
              -> [Maybe String] -- ^ Documentation to attach to arguments
    
    1124 1124
              -> Q Dec
    
    1125 1125
     funD_doc nm cs mfun_doc arg_docs = do
    
    1126
    -  qAddModFinalizer $ sequence_
    
    1126
    +  addModFinalizer $ sequence_
    
    1127 1127
         [putDoc (ArgDoc nm i) s | (i, Just s) <- zip [0..] arg_docs]
    
    1128 1128
       let dec = funD nm cs
    
    1129 1129
       case mfun_doc of
    
    ... ... @@ -1140,7 +1140,7 @@ dataD_doc :: Q Cxt -> Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind)
    1140 1140
               -- ^ Documentation to attach to the data declaration
    
    1141 1141
               -> Q Dec
    
    1142 1142
     dataD_doc ctxt tc tvs ksig cons_with_docs derivs mdoc = do
    
    1143
    -  qAddModFinalizer $ mapM_ docCons cons_with_docs
    
    1143
    +  addModFinalizer $ mapM_ docCons cons_with_docs
    
    1144 1144
       let dec = dataD ctxt tc tvs ksig (map (\(con, _, _) -> con) cons_with_docs) derivs
    
    1145 1145
       maybe dec (flip withDecDoc dec) mdoc
    
    1146 1146
     
    
    ... ... @@ -1154,7 +1154,7 @@ newtypeD_doc :: Q Cxt -> Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind)
    1154 1154
                  -- ^ Documentation to attach to the newtype declaration
    
    1155 1155
                  -> Q Dec
    
    1156 1156
     newtypeD_doc ctxt tc tvs ksig con_with_docs@(con, _, _) derivs mdoc = do
    
    1157
    -  qAddModFinalizer $ docCons con_with_docs
    
    1157
    +  addModFinalizer $ docCons con_with_docs
    
    1158 1158
       let dec = newtypeD ctxt tc tvs ksig con derivs
    
    1159 1159
       maybe dec (flip withDecDoc dec) mdoc
    
    1160 1160
     
    
    ... ... @@ -1167,7 +1167,7 @@ typeDataD_doc :: Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind)
    1167 1167
               -- ^ Documentation to attach to the data declaration
    
    1168 1168
               -> Q Dec
    
    1169 1169
     typeDataD_doc tc tvs ksig cons_with_docs mdoc = do
    
    1170
    -  qAddModFinalizer $ mapM_ docCons cons_with_docs
    
    1170
    +  addModFinalizer $ mapM_ docCons cons_with_docs
    
    1171 1171
       let dec = typeDataD tc tvs ksig (map (\(con, _, _) -> con) cons_with_docs)
    
    1172 1172
       maybe dec (flip withDecDoc dec) mdoc
    
    1173 1173
     
    
    ... ... @@ -1181,7 +1181,7 @@ dataInstD_doc :: Q Cxt -> (Maybe [Q (TyVarBndr ())]) -> Q Type -> Maybe (Q Kind)
    1181 1181
                   -- ^ Documentation to attach to the instance declaration
    
    1182 1182
                   -> Q Dec
    
    1183 1183
     dataInstD_doc ctxt mb_bndrs ty ksig cons_with_docs derivs mdoc = do
    
    1184
    -  qAddModFinalizer $ mapM_ docCons cons_with_docs
    
    1184
    +  addModFinalizer $ mapM_ docCons cons_with_docs
    
    1185 1185
       let dec = dataInstD ctxt mb_bndrs ty ksig (map (\(con, _, _) -> con) cons_with_docs)
    
    1186 1186
                   derivs
    
    1187 1187
       maybe dec (flip withDecDoc dec) mdoc
    
    ... ... @@ -1197,7 +1197,7 @@ newtypeInstD_doc :: Q Cxt -> (Maybe [Q (TyVarBndr ())]) -> Q Type
    1197 1197
                      -- ^ Documentation to attach to the instance declaration
    
    1198 1198
                      -> Q Dec
    
    1199 1199
     newtypeInstD_doc ctxt mb_bndrs ty ksig con_with_docs@(con, _, _) derivs mdoc = do
    
    1200
    -  qAddModFinalizer $ docCons con_with_docs
    
    1200
    +  addModFinalizer $ docCons con_with_docs
    
    1201 1201
       let dec = newtypeInstD ctxt mb_bndrs ty ksig con derivs
    
    1202 1202
       maybe dec (flip withDecDoc dec) mdoc
    
    1203 1203
     
    
    ... ... @@ -1207,7 +1207,7 @@ patSynD_doc :: Name -> Q PatSynArgs -> Q PatSynDir -> Q Pat
    1207 1207
                 -> [Maybe String] -- ^ Documentation to attach to the pattern arguments
    
    1208 1208
                 -> Q Dec
    
    1209 1209
     patSynD_doc name args dir pat mdoc arg_docs = do
    
    1210
    -  qAddModFinalizer $ sequence_
    
    1210
    +  addModFinalizer $ sequence_
    
    1211 1211
         [putDoc (ArgDoc name i) s | (i, Just s) <- zip [0..] arg_docs]
    
    1212 1212
       let dec = patSynD name args dir pat
    
    1213 1213
       maybe dec (flip withDecDoc dec) mdoc
    

  • libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
    ... ... @@ -52,175 +52,6 @@ import GHC.Internal.ForeignSrcLang
    52 52
     import GHC.Internal.LanguageExtensions
    
    53 53
     import GHC.Internal.TH.Syntax
    
    54 54
     
    
    55
    ------------------------------------------------------
    
    56
    ---
    
    57
    ---              The Quasi class
    
    58
    ---
    
    59
    ------------------------------------------------------
    
    60
    -
    
    61
    -class (MonadIO m, MonadFail m) => Quasi m where
    
    62
    -  qRunQ :: Q a -> m a
    
    63
    -  -- | Fresh names. See 'newName'.
    
    64
    -  qNewName :: String -> m Name
    
    65
    -
    
    66
    -  ------- Error reporting and recovery -------
    
    67
    -  -- | Report an error (True) or warning (False)
    
    68
    -  -- ...but carry on; use 'fail' to stop. See 'report'.
    
    69
    -  qReport  :: Bool -> String -> m ()
    
    70
    -
    
    71
    -  -- | See 'recover'.
    
    72
    -  qRecover :: m a -- ^ the error handler
    
    73
    -           -> m a -- ^ action which may fail
    
    74
    -           -> m a -- ^ Recover from the monadic 'fail'
    
    75
    -
    
    76
    -  ------- Inspect the type-checker's environment -------
    
    77
    -  -- | True <=> type namespace, False <=> value namespace. See 'lookupName'.
    
    78
    -  qLookupName :: Bool -> String -> m (Maybe Name)
    
    79
    -  -- | See 'reify'.
    
    80
    -  qReify          :: Name -> m Info
    
    81
    -  -- | See 'reifyFixity'.
    
    82
    -  qReifyFixity    :: Name -> m (Maybe Fixity)
    
    83
    -  -- | See 'reifyType'.
    
    84
    -  qReifyType      :: Name -> m Type
    
    85
    -  -- | Is (n tys) an instance? Returns list of matching instance Decs (with
    
    86
    -  -- empty sub-Decs) Works for classes and type functions. See 'reifyInstances'.
    
    87
    -  qReifyInstances :: Name -> [Type] -> m [Dec]
    
    88
    -  -- | See 'reifyRoles'.
    
    89
    -  qReifyRoles         :: Name -> m [Role]
    
    90
    -  -- | See 'reifyAnnotations'.
    
    91
    -  qReifyAnnotations   :: Data a => AnnLookup -> m [a]
    
    92
    -  -- | See 'reifyModule'.
    
    93
    -  qReifyModule        :: Module -> m ModuleInfo
    
    94
    -  -- | See 'reifyConStrictness'.
    
    95
    -  qReifyConStrictness :: Name -> m [DecidedStrictness]
    
    96
    -
    
    97
    -  -- | See 'location'.
    
    98
    -  qLocation :: m Loc
    
    99
    -
    
    100
    -  -- | Input/output (dangerous). See 'runIO'.
    
    101
    -  qRunIO :: IO a -> m a
    
    102
    -  qRunIO = liftIO
    
    103
    -  -- | See 'getPackageRoot'.
    
    104
    -  qGetPackageRoot :: m FilePath
    
    105
    -
    
    106
    -  -- | See 'addDependentFile'.
    
    107
    -  qAddDependentFile :: FilePath -> m ()
    
    108
    -
    
    109
    -  -- | See 'addDependentDirectory'.
    
    110
    -  qAddDependentDirectory :: FilePath -> m ()
    
    111
    -
    
    112
    -  -- | See 'addTempFile'.
    
    113
    -  qAddTempFile :: String -> m FilePath
    
    114
    -
    
    115
    -  -- | See 'addTopDecls'.
    
    116
    -  qAddTopDecls :: [Dec] -> m ()
    
    117
    -
    
    118
    -  -- | See 'addForeignFilePath'.
    
    119
    -  qAddForeignFilePath :: ForeignSrcLang -> String -> m ()
    
    120
    -
    
    121
    -  -- | See 'addModFinalizer'.
    
    122
    -  qAddModFinalizer :: Q () -> m ()
    
    123
    -
    
    124
    -  -- | See 'addCorePlugin'.
    
    125
    -  qAddCorePlugin :: String -> m ()
    
    126
    -
    
    127
    -  -- | See 'getQ'.
    
    128
    -  qGetQ :: Typeable a => m (Maybe a)
    
    129
    -
    
    130
    -  -- | See 'putQ'.
    
    131
    -  qPutQ :: Typeable a => a -> m ()
    
    132
    -
    
    133
    -  -- | See 'isExtEnabled'.
    
    134
    -  qIsExtEnabled :: Extension -> m Bool
    
    135
    -  -- | See 'extsEnabled'.
    
    136
    -  qExtsEnabled :: m [Extension]
    
    137
    -
    
    138
    -  -- | See 'putDoc'.
    
    139
    -  qPutDoc :: DocLoc -> String -> m ()
    
    140
    -  -- | See 'getDoc'.
    
    141
    -  qGetDoc :: DocLoc -> m (Maybe String)
    
    142
    -
    
    143
    ------------------------------------------------------
    
    144
    ---      The IO instance of Quasi
    
    145
    ------------------------------------------------------
    
    146
    -
    
    147
    ---  | This instance is used only when running a Q
    
    148
    ---  computation in the IO monad, usually just to
    
    149
    ---  print the result.  There is no interesting
    
    150
    ---  type environment, so reification isn't going to
    
    151
    ---  work.
    
    152
    -instance Quasi IO where
    
    153
    -  qRunQ (Q m) = m metaHandlersIO
    
    154
    -  qNewName = newNameIO
    
    155
    -
    
    156
    -  qReport True  msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    157
    -  qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    158
    -
    
    159
    -  qLookupName _ _       = badIO "lookupName"
    
    160
    -  qReify _              = badIO "reify"
    
    161
    -  qReifyFixity _        = badIO "reifyFixity"
    
    162
    -  qReifyType _          = badIO "reifyFixity"
    
    163
    -  qReifyInstances _ _   = badIO "reifyInstances"
    
    164
    -  qReifyRoles _         = badIO "reifyRoles"
    
    165
    -  qReifyAnnotations _   = badIO "reifyAnnotations"
    
    166
    -  qReifyModule _        = badIO "reifyModule"
    
    167
    -  qReifyConStrictness _ = badIO "reifyConStrictness"
    
    168
    -  qLocation             = badIO "currentLocation"
    
    169
    -  qRecover _ _          = badIO "recover" -- Maybe we could fix this?
    
    170
    -  qGetPackageRoot       = badIO "getProjectRoot"
    
    171
    -  qAddDependentFile _   = badIO "addDependentFile"
    
    172
    -  qAddTempFile _        = badIO "addTempFile"
    
    173
    -  qAddTopDecls _        = badIO "addTopDecls"
    
    174
    -  qAddForeignFilePath _ _ = badIO "addForeignFilePath"
    
    175
    -  qAddModFinalizer _    = badIO "addModFinalizer"
    
    176
    -  qAddCorePlugin _      = badIO "addCorePlugin"
    
    177
    -  qGetQ                 = badIO "getQ"
    
    178
    -  qPutQ _               = badIO "putQ"
    
    179
    -  qIsExtEnabled _       = badIO "isExtEnabled"
    
    180
    -  qExtsEnabled          = badIO "extsEnabled"
    
    181
    -  qPutDoc _ _           = badIO "putDoc"
    
    182
    -  qGetDoc _             = badIO "getDoc"
    
    183
    -  qAddDependentDirectory _ = badIO "AddDependentDirectory"
    
    184
    -
    
    185
    -metaHandlersIO :: MetaHandlers IO
    
    186
    -metaHandlersIO  = MetaHandlers {
    
    187
    -    mFail = fail
    
    188
    -  , mNewName = newNameIO
    
    189
    -  , mReport = \b msg ->
    
    190
    -     if b then
    
    191
    -       hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    192
    -     else
    
    193
    -       hPutStrLn stderr ("Template Haskell error: " ++ msg) -- TODO: should this be different from above?
    
    194
    -  , mLookupName           = \ _ _ -> badIO "lookupName"
    
    195
    -  , mReify                = \_ -> badIO "reify"
    
    196
    -  , mReifyFixity          = \_ -> badIO "reifyFixity"
    
    197
    -  , mReifyType            = \_ -> badIO "reifyFixity"
    
    198
    -  , mReifyInstances       = \_ _ -> badIO "reifyInstances"
    
    199
    -  , mReifyRoles           = \_ -> badIO "reifyRoles"
    
    200
    -  , mReifyAnnotations     = \_ -> badIO "reifyAnnotations"
    
    201
    -  , mReifyModule          = \_ -> badIO "reifyModule"
    
    202
    -  , mReifyConStrictness   = \_ -> badIO "reifyConStrictness"
    
    203
    -  , mLocation             = badIO "currentLocation"
    
    204
    -  , mRecover              = \_ _ -> badIO "recover" -- Maybe we could fix this?
    
    205
    -  , mGetPackageRoot       = badIO "getProjectRoot"
    
    206
    -  , mAddDependentFile     = \_ -> badIO "addDependentFile"
    
    207
    -  , mAddTempFile          = \_ -> badIO "addTempFile"
    
    208
    -  , mAddTopDecls          = \_ -> badIO "addTopDecls"
    
    209
    -  , mAddForeignFilePath   = \_ _ -> badIO "addForeignFilePath"
    
    210
    -  , mAddModFinalizer      = \_ -> badIO "addModFinalizer"
    
    211
    -  , mAddCorePlugin        = \_ -> badIO "addCorePlugin"
    
    212
    -  , mGetQ                 = badIO "getQ"
    
    213
    -  , mPutQ                 = \_ -> badIO "putQ"
    
    214
    -  , mIsExtEnabled         = \_ -> badIO "isExtEnabled"
    
    215
    -  , mExtsEnabled          = badIO "extsEnabled"
    
    216
    -  , mPutDoc               = \_ _ -> badIO "putDoc"
    
    217
    -  , mGetDoc               = \_ -> badIO "getDoc"
    
    218
    -  , mAddDependentDirectory = \_ -> badIO "AddDependentDirectory"
    
    219
    -  }
    
    220
    -
    
    221
    -instance Quote IO where
    
    222
    -  newName = newNameIO
    
    223
    -
    
    224 55
     data MetaHandlers m = MetaHandlers {
    
    225 56
         mFail :: forall a. String -> m a
    
    226 57
         -- | Fresh names. See 'newName'.
    
    ... ... @@ -301,15 +132,55 @@ data MetaHandlers m = MetaHandlers {
    301 132
         , mGetDoc :: DocLoc -> m (Maybe String)
    
    302 133
       }
    
    303 134
     
    
    135
    +badIO :: String -> IO a
    
    136
    +badIO op = do   { hPutStrLn stderr ("Can't do `" ++ op ++ "' in the IO monad")
    
    137
    +                ; fail "Template Haskell failure" }
    
    138
    +
    
    139
    +metaHandlersIO :: MetaHandlers IO
    
    140
    +metaHandlersIO  = MetaHandlers {
    
    141
    +    mFail = fail
    
    142
    +  , mNewName = newNameIO
    
    143
    +  , mReport = \b msg ->
    
    144
    +     if b then
    
    145
    +       hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    146
    +     else
    
    147
    +       hPutStrLn stderr ("Template Haskell error: " ++ msg) -- TODO: should this be different from above?
    
    148
    +  , mLookupName           = \ _ _ -> badIO "lookupName"
    
    149
    +  , mReify                = \_ -> badIO "reify"
    
    150
    +  , mReifyFixity          = \_ -> badIO "reifyFixity"
    
    151
    +  , mReifyType            = \_ -> badIO "reifyFixity"
    
    152
    +  , mReifyInstances       = \_ _ -> badIO "reifyInstances"
    
    153
    +  , mReifyRoles           = \_ -> badIO "reifyRoles"
    
    154
    +  , mReifyAnnotations     = \_ -> badIO "reifyAnnotations"
    
    155
    +  , mReifyModule          = \_ -> badIO "reifyModule"
    
    156
    +  , mReifyConStrictness   = \_ -> badIO "reifyConStrictness"
    
    157
    +  , mLocation             = badIO "currentLocation"
    
    158
    +  , mRecover              = \_ _ -> badIO "recover" -- Maybe we could fix this?
    
    159
    +  , mGetPackageRoot       = badIO "getProjectRoot"
    
    160
    +  , mAddDependentFile     = \_ -> badIO "addDependentFile"
    
    161
    +  , mAddTempFile          = \_ -> badIO "addTempFile"
    
    162
    +  , mAddTopDecls          = \_ -> badIO "addTopDecls"
    
    163
    +  , mAddForeignFilePath   = \_ _ -> badIO "addForeignFilePath"
    
    164
    +  , mAddModFinalizer      = \_ -> badIO "addModFinalizer"
    
    165
    +  , mAddCorePlugin        = \_ -> badIO "addCorePlugin"
    
    166
    +  , mGetQ                 = badIO "getQ"
    
    167
    +  , mPutQ                 = \_ -> badIO "putQ"
    
    168
    +  , mIsExtEnabled         = \_ -> badIO "isExtEnabled"
    
    169
    +  , mExtsEnabled          = badIO "extsEnabled"
    
    170
    +  , mPutDoc               = \_ _ -> badIO "putDoc"
    
    171
    +  , mGetDoc               = \_ -> badIO "getDoc"
    
    172
    +  , mAddDependentDirectory = \_ -> badIO "AddDependentDirectory"
    
    173
    +  }
    
    174
    +
    
    175
    +instance Quote IO where
    
    176
    +  newName = newNameIO
    
    177
    +
    
    178
    +
    
    304 179
     
    
    305 180
     newNameIO :: String -> IO Name
    
    306 181
     newNameIO s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x))
    
    307 182
                      ; pure (mkNameU s n) }
    
    308 183
     
    
    309
    -badIO :: String -> IO a
    
    310
    -badIO op = do   { qReport True ("Can't do `" ++ op ++ "' in the IO monad")
    
    311
    -                ; fail "Template Haskell failure" }
    
    312
    -
    
    313 184
     -- Global variable to generate unique symbols
    
    314 185
     counter :: IORef Uniq
    
    315 186
     {-# NOINLINE counter #-}
    
    ... ... @@ -334,20 +205,6 @@ counter = unsafePerformIO (newIORef 0)
    334 205
     -- fufilled by an concrete 'Quasi' instance, internal to GHC.
    
    335 206
     newtype Q a = Q { unQ :: MetaHandlers IO -> IO a }
    
    336 207
     
    
    337
    --- | \"Runs\" the 'Q' monad. Normal users of Template Haskell
    
    338
    --- should not need this function, as the splice brackets @$( ... )@
    
    339
    --- are the usual way of running a 'Q' computation.
    
    340
    ---
    
    341
    --- This function is primarily used in GHC internals, and for debugging
    
    342
    --- splices by running them in 'IO'.
    
    343
    ---
    
    344
    --- Note that many functions in 'Q', such as 'reify' and other compiler
    
    345
    --- queries, are not supported when running 'Q' in 'IO'; these operations
    
    346
    --- simply fail at runtime. Indeed, the only operations guaranteed to succeed
    
    347
    --- are 'newName', 'runIO', 'reportError' and 'reportWarning'.
    
    348
    -runQ :: Quasi m => Q a -> m a
    
    349
    -runQ = qRunQ
    
    350
    -
    
    351 208
     instance Monad Q where
    
    352 209
       Q m >>= k  = Q $ \h -> (m h >>= \x -> unQ (k x) h)
    
    353 210
       (>>) = (*>)
    
    ... ... @@ -430,14 +287,17 @@ class Monad m => Quote m where
    430 287
       -}
    
    431 288
       newName :: String -> m Name
    
    432 289
     
    
    290
    +-- | Utility function for lifting a 0-ary method of 'MetaHandlers' into 'Q'
    
    433 291
     runHandler :: (forall m. MetaHandlers m -> m a) -> Q a
    
    434
    -runHandler op = Q $ \h -> (op h)
    
    292
    +runHandler op = Q $ \h -> op h
    
    435 293
     
    
    294
    +-- | Utility function for lifting a 1-ary method of 'MetaHandlers' into 'Q'
    
    436 295
     runHandler1 :: (forall m. MetaHandlers m -> a -> m b) -> a -> Q b
    
    437
    -runHandler1 op = \x -> Q $ \h -> (op h x)
    
    296
    +runHandler1 op = \x -> Q $ \h -> op h x
    
    438 297
     
    
    298
    +-- | Utility function for lifting a 2-ary method of 'MetaHandlers' into 'Q'
    
    439 299
     runHandler2 :: (forall m. MetaHandlers m -> a -> b -> m c) -> a -> b -> Q c
    
    440
    -runHandler2 op = \x y -> Q $ \h -> (op h x y)
    
    300
    +runHandler2 op = \x y -> Q $ \h -> op h x y
    
    441 301
     
    
    442 302
     instance Quote Q where
    
    443 303
       newName = runHandler1 mNewName
    
    ... ... @@ -658,15 +518,15 @@ recover rec main = Q $ \h -> mRecover h rec main
    658 518
     -- We don't export lookupName; the Bool isn't a great API
    
    659 519
     -- Instead we export lookupTypeName, lookupValueName
    
    660 520
     lookupName :: Bool -> String -> Q (Maybe Name)
    
    661
    -lookupName ns s = runHandler2 mLookupName ns s
    
    521
    +lookupName = runHandler2 mLookupName
    
    662 522
     
    
    663 523
     -- | Look up the given name in the (type namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
    
    664 524
     lookupTypeName :: String -> Q (Maybe Name)
    
    665
    -lookupTypeName  s = runHandler2 mLookupName True s
    
    525
    +lookupTypeName = runHandler2 mLookupName True
    
    666 526
     
    
    667 527
     -- | Look up the given name in the (value namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
    
    668 528
     lookupValueName :: String -> Q (Maybe Name)
    
    669
    -lookupValueName s = runHandler2 mLookupName False s
    
    529
    +lookupValueName = runHandler2 mLookupName False
    
    670 530
     
    
    671 531
     {-
    
    672 532
     Note [Name lookup]
    
    ... ... @@ -850,7 +710,7 @@ has some discussion around this.
    850 710
     
    
    851 711
     -}
    
    852 712
     reifyInstances :: Name -> [Type] -> Q [InstanceDec]
    
    853
    -reifyInstances cls tys = runHandler2 mReifyInstances cls tys
    
    713
    +reifyInstances = runHandler2 mReifyInstances
    
    854 714
     
    
    855 715
     {- | @reifyRoles nm@ returns the list of roles associated with the parameters
    
    856 716
     (both visible and invisible) of
    
    ... ... @@ -869,20 +729,20 @@ and @reifyRoles Proxy@, we will get @['NominalR', 'PhantomR']@. The 'NominalR' i
    869 729
     the role of the invisible @k@ parameter. Kind parameters are always nominal.
    
    870 730
     -}
    
    871 731
     reifyRoles :: Name -> Q [Role]
    
    872
    -reifyRoles nm = runHandler1 mReifyRoles nm
    
    732
    +reifyRoles = runHandler1 mReifyRoles
    
    873 733
     
    
    874 734
     -- | @reifyAnnotations target@ returns the list of annotations
    
    875 735
     -- associated with @target@.  Only the annotations that are
    
    876 736
     -- appropriately typed is returned.  So if you have @Int@ and @String@
    
    877 737
     -- annotations for the same target, you have to call this function twice.
    
    878 738
     reifyAnnotations :: Data a => AnnLookup -> Q [a]
    
    879
    -reifyAnnotations an = runHandler1 mReifyAnnotations an
    
    739
    +reifyAnnotations = runHandler1 mReifyAnnotations
    
    880 740
     
    
    881 741
     -- | @reifyModule mod@ looks up information about module @mod@.  To
    
    882 742
     -- look up the current module, call this function with the return
    
    883 743
     -- value of 'Language.Haskell.TH.Lib.thisModule'.
    
    884 744
     reifyModule :: Module -> Q ModuleInfo
    
    885
    -reifyModule m = runHandler1 mReifyModule m
    
    745
    +reifyModule = runHandler1 mReifyModule
    
    886 746
     
    
    887 747
     -- | @reifyConStrictness nm@ looks up the strictness information for the fields
    
    888 748
     -- of the constructor with the name @nm@. Note that the strictness information
    
    ... ... @@ -897,7 +757,7 @@ reifyModule m = runHandler1 mReifyModule m
    897 757
     -- circumstances, but it would return @['DecidedStrict', DecidedStrict]@ if the
    
    898 758
     -- @-XStrictData@ language extension was enabled.
    
    899 759
     reifyConStrictness :: Name -> Q [DecidedStrictness]
    
    900
    -reifyConStrictness n = runHandler1 mReifyConStrictness n
    
    760
    +reifyConStrictness = runHandler1 mReifyConStrictness
    
    901 761
     
    
    902 762
     -- | Is the list of instances returned by 'reifyInstances' nonempty?
    
    903 763
     --
    
    ... ... @@ -951,7 +811,7 @@ getPackageRoot = runHandler mGetPackageRoot
    951 811
     --   * The state of the directory is read at the interface generation time,
    
    952 812
     --     not at the time of the function call.
    
    953 813
     addDependentDirectory :: FilePath -> Q ()
    
    954
    -addDependentDirectory dp = runHandler1 mAddDependentDirectory dp
    
    814
    +addDependentDirectory = runHandler1 mAddDependentDirectory
    
    955 815
     
    
    956 816
     -- | Record external files that runIO is using (dependent upon).
    
    957 817
     -- The compiler can then recognize that it should re-compile the Haskell file
    
    ... ... @@ -965,17 +825,17 @@ addDependentDirectory dp = runHandler1 mAddDependentDirectory dp
    965 825
     --
    
    966 826
     --   * The dependency is based on file content, not a modification time
    
    967 827
     addDependentFile :: FilePath -> Q ()
    
    968
    -addDependentFile fp = runHandler1 mAddDependentFile fp
    
    828
    +addDependentFile = runHandler1 mAddDependentFile
    
    969 829
     
    
    970 830
     -- | Obtain a temporary file path with the given suffix. The compiler will
    
    971 831
     -- delete this file after compilation.
    
    972 832
     addTempFile :: String -> Q FilePath
    
    973
    -addTempFile suffix = runHandler1 mAddTempFile suffix
    
    833
    +addTempFile = runHandler1 mAddTempFile
    
    974 834
     
    
    975 835
     -- | Add additional top-level declarations. The added declarations will be type
    
    976 836
     -- checked along with the current declaration group.
    
    977 837
     addTopDecls :: [Dec] -> Q ()
    
    978
    -addTopDecls ds = runHandler1 mAddTopDecls ds
    
    838
    +addTopDecls = runHandler1 mAddTopDecls
    
    979 839
     
    
    980 840
     -- | Same as 'addForeignSource', but expects to receive a path pointing to the
    
    981 841
     -- foreign file instead of a 'String' of its contents. Consider using this in
    
    ... ... @@ -984,7 +844,7 @@ addTopDecls ds = runHandler1 mAddTopDecls ds
    984 844
     -- This is a good alternative to 'addForeignSource' when you are trying to
    
    985 845
     -- directly link in an object file.
    
    986 846
     addForeignFilePath :: ForeignSrcLang -> FilePath -> Q ()
    
    987
    -addForeignFilePath lang fp = runHandler2 mAddForeignFilePath lang fp
    
    847
    +addForeignFilePath = runHandler2 mAddForeignFilePath
    
    988 848
     
    
    989 849
     -- | Add a finalizer that will run in the Q monad after the current module has
    
    990 850
     -- been type checked. This only makes sense when run within a top-level splice.
    
    ... ... @@ -993,7 +853,7 @@ addForeignFilePath lang fp = runHandler2 mAddForeignFilePath lang fp
    993 853
     -- 'reify' is able to find the local definitions when executed inside the
    
    994 854
     -- finalizer.
    
    995 855
     addModFinalizer :: Q () -> Q ()
    
    996
    -addModFinalizer act = runHandler1 mAddModFinalizer act
    
    856
    +addModFinalizer = runHandler1 mAddModFinalizer
    
    997 857
     
    
    998 858
     -- | Adds a core plugin to the compilation pipeline.
    
    999 859
     --
    
    ... ... @@ -1003,7 +863,7 @@ addModFinalizer act = runHandler1 mAddModFinalizer act
    1003 863
     -- to tell the compiler that we needed to compile first a plugin module in the
    
    1004 864
     -- current package.
    
    1005 865
     addCorePlugin :: String -> Q ()
    
    1006
    -addCorePlugin plugin = runHandler1 mAddCorePlugin plugin
    
    866
    +addCorePlugin = runHandler1 mAddCorePlugin
    
    1007 867
     
    
    1008 868
     -- | Get state from the 'Q' monad. The state maintained by 'Q' is isomorphic to
    
    1009 869
     -- a type-indexed finite map. That is,
    
    ... ... @@ -1022,11 +882,11 @@ getQ = runHandler mGetQ
    1022 882
     -- | Replace the state in the 'Q' monad. Note that the state is local to the
    
    1023 883
     -- Haskell module in which the Template Haskell expression is executed.
    
    1024 884
     putQ :: Typeable a => a -> Q ()
    
    1025
    -putQ x = runHandler1 mPutQ x
    
    885
    +putQ = runHandler1 mPutQ
    
    1026 886
     
    
    1027 887
     -- | Determine whether the given language extension is enabled in the 'Q' monad.
    
    1028 888
     isExtEnabled :: Extension -> Q Bool
    
    1029
    -isExtEnabled ext = runHandler1 mIsExtEnabled ext
    
    889
    +isExtEnabled = runHandler1 mIsExtEnabled
    
    1030 890
     
    
    1031 891
     -- | List all enabled language extensions.
    
    1032 892
     extsEnabled :: Q [Extension]
    
    ... ... @@ -1049,49 +909,18 @@ extsEnabled = runHandler mExtsEnabled
    1049 909
     -- Adding documentation to anything outside of the current module will cause an
    
    1050 910
     -- error.
    
    1051 911
     putDoc :: DocLoc -> String -> Q ()
    
    1052
    -putDoc t s = runHandler2 mPutDoc t s
    
    912
    +putDoc = runHandler2 mPutDoc
    
    1053 913
     
    
    1054 914
     -- | Retrieves the Haddock documentation at the specified location, if one
    
    1055 915
     -- exists.
    
    1056 916
     -- It can be used to read documentation on things defined outside of the current
    
    1057 917
     -- module, provided that those modules were compiled with the @-haddock@ flag.
    
    1058 918
     getDoc :: DocLoc -> Q (Maybe String)
    
    1059
    -getDoc n = runHandler1 mGetDoc n
    
    919
    +getDoc = runHandler1 mGetDoc
    
    1060 920
     
    
    1061 921
     instance MonadIO Q where
    
    1062 922
       liftIO = runIO
    
    1063 923
     
    
    1064
    -instance Quasi Q where
    
    1065
    -  qRunQ               = id
    
    1066
    -  qNewName            = newName
    
    1067
    -  qReport             = report
    
    1068
    -  qRecover            = recover
    
    1069
    -  qReify              = reify
    
    1070
    -  qReifyFixity        = reifyFixity
    
    1071
    -  qReifyType          = reifyType
    
    1072
    -  qReifyInstances     = reifyInstances
    
    1073
    -  qReifyRoles         = reifyRoles
    
    1074
    -  qReifyAnnotations   = reifyAnnotations
    
    1075
    -  qReifyModule        = reifyModule
    
    1076
    -  qReifyConStrictness = reifyConStrictness
    
    1077
    -  qLookupName         = lookupName
    
    1078
    -  qLocation           = location
    
    1079
    -  qGetPackageRoot     = getPackageRoot
    
    1080
    -  qAddDependentFile   = addDependentFile
    
    1081
    -  qAddDependentDirectory = addDependentDirectory
    
    1082
    -  qAddTempFile        = addTempFile
    
    1083
    -  qAddTopDecls        = addTopDecls
    
    1084
    -  qAddForeignFilePath = addForeignFilePath
    
    1085
    -  qAddModFinalizer    = addModFinalizer
    
    1086
    -  qAddCorePlugin      = addCorePlugin
    
    1087
    -  qGetQ               = getQ
    
    1088
    -  qPutQ               = putQ
    
    1089
    -  qIsExtEnabled       = isExtEnabled
    
    1090
    -  qExtsEnabled        = extsEnabled
    
    1091
    -  qPutDoc             = putDoc
    
    1092
    -  qGetDoc             = getDoc
    
    1093
    -
    
    1094
    -
    
    1095 924
     ----------------------------------------------------
    
    1096 925
     -- The following operations are used solely in GHC.HsToCore.Quote when
    
    1097 926
     -- desugaring brackets. They are not necessary for the user, who can use
    

  • libraries/template-haskell/Language/Haskell/TH/Syntax.hs
    ... ... @@ -504,3 +504,181 @@ pattern SpecialiseP nm ty inl phases = SpecialiseEP Nothing [] (SigE (VarE nm) t
    504 504
     
    
    505 505
     unQ :: Q a -> (forall m. Quasi m => m a)
    
    506 506
     unQ m =  runQ m
    
    507
    +
    
    508
    +-----------------------------------------------------
    
    509
    +--
    
    510
    +--              The Quasi class
    
    511
    +--
    
    512
    +-----------------------------------------------------
    
    513
    +
    
    514
    +class (MonadIO m, MonadFail m) => Quasi m where
    
    515
    +  qRunQ :: Q a -> m a
    
    516
    +  -- | Fresh names. See 'newName'.
    
    517
    +  qNewName :: String -> m Name
    
    518
    +
    
    519
    +  ------- Error reporting and recovery -------
    
    520
    +  -- | Report an error (True) or warning (False)
    
    521
    +  -- ...but carry on; use 'fail' to stop. See 'report'.
    
    522
    +  qReport  :: Bool -> String -> m ()
    
    523
    +
    
    524
    +  -- | See 'recover'.
    
    525
    +  qRecover :: m a -- ^ the error handler
    
    526
    +           -> m a -- ^ action which may fail
    
    527
    +           -> m a -- ^ Recover from the monadic 'fail'
    
    528
    +
    
    529
    +  ------- Inspect the type-checker's environment -------
    
    530
    +  -- | True <=> type namespace, False <=> value namespace. See 'lookupName'.
    
    531
    +  qLookupName :: Bool -> String -> m (Maybe Name)
    
    532
    +  -- | See 'reify'.
    
    533
    +  qReify          :: Name -> m Info
    
    534
    +  -- | See 'reifyFixity'.
    
    535
    +  qReifyFixity    :: Name -> m (Maybe Fixity)
    
    536
    +  -- | See 'reifyType'.
    
    537
    +  qReifyType      :: Name -> m Type
    
    538
    +  -- | Is (n tys) an instance? Returns list of matching instance Decs (with
    
    539
    +  -- empty sub-Decs) Works for classes and type functions. See 'reifyInstances'.
    
    540
    +  qReifyInstances :: Name -> [Type] -> m [Dec]
    
    541
    +  -- | See 'reifyRoles'.
    
    542
    +  qReifyRoles         :: Name -> m [Role]
    
    543
    +  -- | See 'reifyAnnotations'.
    
    544
    +  qReifyAnnotations   :: Data a => AnnLookup -> m [a]
    
    545
    +  -- | See 'reifyModule'.
    
    546
    +  qReifyModule        :: Module -> m ModuleInfo
    
    547
    +  -- | See 'reifyConStrictness'.
    
    548
    +  qReifyConStrictness :: Name -> m [DecidedStrictness]
    
    549
    +
    
    550
    +  -- | See 'location'.
    
    551
    +  qLocation :: m Loc
    
    552
    +
    
    553
    +  -- | Input/output (dangerous). See 'runIO'.
    
    554
    +  qRunIO :: IO a -> m a
    
    555
    +  qRunIO = liftIO
    
    556
    +  -- | See 'getPackageRoot'.
    
    557
    +  qGetPackageRoot :: m FilePath
    
    558
    +
    
    559
    +  -- | See 'addDependentFile'.
    
    560
    +  qAddDependentFile :: FilePath -> m ()
    
    561
    +
    
    562
    +  -- | See 'addDependentDirectory'.
    
    563
    +  qAddDependentDirectory :: FilePath -> m ()
    
    564
    +
    
    565
    +  -- | See 'addTempFile'.
    
    566
    +  qAddTempFile :: String -> m FilePath
    
    567
    +
    
    568
    +  -- | See 'addTopDecls'.
    
    569
    +  qAddTopDecls :: [Dec] -> m ()
    
    570
    +
    
    571
    +  -- | See 'addForeignFilePath'.
    
    572
    +  qAddForeignFilePath :: ForeignSrcLang -> String -> m ()
    
    573
    +
    
    574
    +  -- | See 'addModFinalizer'.
    
    575
    +  qAddModFinalizer :: Q () -> m ()
    
    576
    +
    
    577
    +  -- | See 'addCorePlugin'.
    
    578
    +  qAddCorePlugin :: String -> m ()
    
    579
    +
    
    580
    +  -- | See 'getQ'.
    
    581
    +  qGetQ :: Typeable a => m (Maybe a)
    
    582
    +
    
    583
    +  -- | See 'putQ'.
    
    584
    +  qPutQ :: Typeable a => a -> m ()
    
    585
    +
    
    586
    +  -- | See 'isExtEnabled'.
    
    587
    +  qIsExtEnabled :: Extension -> m Bool
    
    588
    +  -- | See 'extsEnabled'.
    
    589
    +  qExtsEnabled :: m [Extension]
    
    590
    +
    
    591
    +  -- | See 'putDoc'.
    
    592
    +  qPutDoc :: DocLoc -> String -> m ()
    
    593
    +  -- | See 'getDoc'.
    
    594
    +  qGetDoc :: DocLoc -> m (Maybe String)
    
    595
    +
    
    596
    +-- | \"Runs\" the 'Q' monad. Normal users of Template Haskell
    
    597
    +-- should not need this function, as the splice brackets @$( ... )@
    
    598
    +-- are the usual way of running a 'Q' computation.
    
    599
    +--
    
    600
    +-- This function is primarily used in GHC internals, and for debugging
    
    601
    +-- splices by running them in 'IO'.
    
    602
    +--
    
    603
    +-- Note that many functions in 'Q', such as 'reify' and other compiler
    
    604
    +-- queries, are not supported when running 'Q' in 'IO'; these operations
    
    605
    +-- simply fail at runtime. Indeed, the only operations guaranteed to succeed
    
    606
    +-- are 'newName', 'runIO', 'reportError' and 'reportWarning'.
    
    607
    +runQ :: Quasi m => Q a -> m a
    
    608
    +runQ = qRunQ
    
    609
    +
    
    610
    +-----------------------------------------------------
    
    611
    +--      The IO instance of Quasi
    
    612
    +-----------------------------------------------------
    
    613
    +
    
    614
    +--  | This instance is used only when running a Q
    
    615
    +--  computation in the IO monad, usually just to
    
    616
    +--  print the result.  There is no interesting
    
    617
    +--  type environment, so reification isn't going to
    
    618
    +--  work.
    
    619
    +instance Quasi IO where
    
    620
    +  qRunQ (Q m) = m metaHandlersIO
    
    621
    +  qNewName = newNameIO
    
    622
    +
    
    623
    +  qReport True  msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    624
    +  qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    625
    +
    
    626
    +  qLookupName _ _       = badIO "lookupName"
    
    627
    +  qReify _              = badIO "reify"
    
    628
    +  qReifyFixity _        = badIO "reifyFixity"
    
    629
    +  qReifyType _          = badIO "reifyFixity"
    
    630
    +  qReifyInstances _ _   = badIO "reifyInstances"
    
    631
    +  qReifyRoles _         = badIO "reifyRoles"
    
    632
    +  qReifyAnnotations _   = badIO "reifyAnnotations"
    
    633
    +  qReifyModule _        = badIO "reifyModule"
    
    634
    +  qReifyConStrictness _ = badIO "reifyConStrictness"
    
    635
    +  qLocation             = badIO "currentLocation"
    
    636
    +  qRecover _ _          = badIO "recover" -- Maybe we could fix this?
    
    637
    +  qGetPackageRoot       = badIO "getProjectRoot"
    
    638
    +  qAddDependentFile _   = badIO "addDependentFile"
    
    639
    +  qAddTempFile _        = badIO "addTempFile"
    
    640
    +  qAddTopDecls _        = badIO "addTopDecls"
    
    641
    +  qAddForeignFilePath _ _ = badIO "addForeignFilePath"
    
    642
    +  qAddModFinalizer _    = badIO "addModFinalizer"
    
    643
    +  qAddCorePlugin _      = badIO "addCorePlugin"
    
    644
    +  qGetQ                 = badIO "getQ"
    
    645
    +  qPutQ _               = badIO "putQ"
    
    646
    +  qIsExtEnabled _       = badIO "isExtEnabled"
    
    647
    +  qExtsEnabled          = badIO "extsEnabled"
    
    648
    +  qPutDoc _ _           = badIO "putDoc"
    
    649
    +  qGetDoc _             = badIO "getDoc"
    
    650
    +  qAddDependentDirectory _ = badIO "AddDependentDirectory"
    
    651
    +
    
    652
    +badIO :: String -> IO a
    
    653
    +badIO op = do   { qReport True ("Can't do `" ++ op ++ "' in the IO monad")
    
    654
    +                ; fail "Template Haskell failure" }
    
    655
    +
    
    656
    +instance Quasi Q where
    
    657
    +  qRunQ               = id
    
    658
    +  qNewName            = newName
    
    659
    +  qReport             = report
    
    660
    +  qRecover            = recover
    
    661
    +  qReify              = reify
    
    662
    +  qReifyFixity        = reifyFixity
    
    663
    +  qReifyType          = reifyType
    
    664
    +  qReifyInstances     = reifyInstances
    
    665
    +  qReifyRoles         = reifyRoles
    
    666
    +  qReifyAnnotations   = reifyAnnotations
    
    667
    +  qReifyModule        = reifyModule
    
    668
    +  qReifyConStrictness = reifyConStrictness
    
    669
    +  qLookupName         = lookupName
    
    670
    +  qLocation           = location
    
    671
    +  qGetPackageRoot     = getPackageRoot
    
    672
    +  qAddDependentFile   = addDependentFile
    
    673
    +  qAddDependentDirectory = addDependentDirectory
    
    674
    +  qAddTempFile        = addTempFile
    
    675
    +  qAddTopDecls        = addTopDecls
    
    676
    +  qAddForeignFilePath = addForeignFilePath
    
    677
    +  qAddModFinalizer    = addModFinalizer
    
    678
    +  qAddCorePlugin      = addCorePlugin
    
    679
    +  qGetQ               = getQ
    
    680
    +  qPutQ               = putQ
    
    681
    +  qIsExtEnabled       = isExtEnabled
    
    682
    +  qExtsEnabled        = extsEnabled
    
    683
    +  qPutDoc             = putDoc
    
    684
    +  qGetDoc             = getDoc