Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
Synopsis
- data Loc = MkLoc {}
- type Expr = HsExpr GhcPs
- type LExpr = LHsExpr GhcPs
- data InScope = MkInScope {}
- noneInScope :: InScope
- addValid :: OccName -> InScope -> InScope
- addValids :: OccSet -> InScope -> InScope
- invalidateVars :: InScope -> InScope
- isInvalid :: Has (Reader InScope) sig m => OccName -> m Bool
- bangLoc :: Loc -> Loc
- bangSpan :: SrcSpan -> SrcSpan
- bangSrcLoc :: SrcLoc -> SrcLoc
- pattern ExprLoc :: Loc -> Expr -> LExpr
- spanToLoc :: RealSrcSpan -> Loc
- replaceBangs :: [CommandLineOption] -> ModSummary -> Handler Hsc ParsedResult
- type family HandleFailure canFail = t | t -> canFail where ...
- class MonadTrans t => HandlingMonadTrans t where
- class Typeable (AstType a) => Handle a where
- handle :: forall a sig m. (Handle a, CanFail a ~ False) => Has (Effects a) sig m => Handler m (AstType a)
- try :: forall e sig m a. (HandlingMonadTrans (HandleFailure (CanFail e)), Typeable a, Handle e, Monad m, Has (Effects e) sig m) => Try m a
- fillHoles :: (Data a, Has (PsErrors :+: (Reader Options :+: (Uniques :+: (LocalVars :+: Reader DynFlags)))) sig m) => Map Loc LExpr -> Handler m a
- evac :: forall a sig m. (Has Fill sig m, Data a) => Handler m a
- tryEvac :: Monad m => [Try m a] -> Try m a
- usualTries :: (Has Fill sig m, Data a) => [Try m a]
- ignore :: forall (e :: Type) m a. (Monad m, Typeable a, Typeable e) => Try m a
- evacPats :: forall a m sig. (Has (Fill :+: State InScope) sig m, Data a) => Handler m a
- addStmts :: forall sig m. Has (PsErrors :+: (HoleFills :+: (Uniques :+: (LocalVars :+: Reader DynFlags)))) sig m => Handler m [ExprLStmt GhcPs]
- type HoleFills = Offer Loc LExpr
- type LocalVars = Reader InScope :+: Writer OccSet
- type Fill = PsErrors :+: (Writer (DList BindStmt) :+: (HoleFills :+: (Uniques :+: (LocalVars :+: Reader DynFlags))))
- data BindStmt = RdrName :<- LExpr
- bindStmtExpr :: BindStmt -> LExpr
- bindStmtSpan :: BindStmt -> SrcSpan
- fromBindStmt :: BindStmt -> ExprLStmt GhcPs
- bangVar :: Has (Uniques :+: Reader DynFlags) sig m => LExpr -> Loc -> m RdrName
- locVar :: Has Uniques sig m => String -> SrcSpan -> Loc -> m RdrName
- tellOne :: Has (Writer (DList w)) sig m => w -> m ()
- tellLocalVar :: Has (Writer OccSet) sig m => OccName -> m ()
Documentation
To keep track of which local variables in scope may be used
If local variables are defined within the same statement as a !, but outside of that !, they must not be used within this !, since their desugaring would make them escape their scope.
invalidateVars :: InScope -> InScope Source #
bangSrcLoc :: SrcLoc -> SrcLoc Source #
Decrement column by one to get the location of a !
spanToLoc :: RealSrcSpan -> Loc Source #
replaceBangs :: [CommandLineOption] -> ModSummary -> Handler Hsc ParsedResult Source #
type family HandleFailure canFail = t | t -> canFail where ... Source #
class MonadTrans t => HandlingMonadTrans t where Source #
class Typeable (AstType a) => Handle a where Source #
handle' :: forall sig m m'. m ~ HandleFailure (CanFail a) m' => Has (Effects a) sig m' => Handler m (AstType a) Source #
Instances
Handle StmtLR Source # | |
Handle HsBindLR Source # | We keep track of any local binds, to prevent the user from using them with ! in situations where they would be evacuated to a place where they're not in scope The plugin would still work without this, but might accept programs that shouldn't be accepted, with unexpected semantics. E.g: do let s = pure "outer" let s = pure "inner" in putStrLn !s You might expect this to print do let s = pure "outer" <!s> <- s let s = pure "inner" in print <!s> With this function, the plugin will instead throw an error saying that
If the first If only the first do let s = pure "outer" putStrLn !s it would be valid code. |
Handle GRHSs Source # | |
Handle Match Source # | |
Handle MatchGroup Source # | |
Defined in MonadicBang.Internal type CanFail MatchGroup :: Bool Source # type AstType MatchGroup = (r :: Type) Source # type Effects MatchGroup :: (Type -> Type) -> Type -> Type Source # handle' :: forall (sig :: (Type -> Type) -> Type -> Type) m (m' :: Type -> Type). (m ~ HandleFailure (CanFail MatchGroup) m', Has (Effects MatchGroup) sig m') => Handler m (AstType MatchGroup) Source # | |
Handle HsExpr Source # | |
Handle Pat Source # | |
handle :: forall a sig m. (Handle a, CanFail a ~ False) => Has (Effects a) sig m => Handler m (AstType a) Source #
try :: forall e sig m a. (HandlingMonadTrans (HandleFailure (CanFail e)), Typeable a, Handle e, Monad m, Has (Effects e) sig m) => Try m a Source #
fillHoles :: (Data a, Has (PsErrors :+: (Reader Options :+: (Uniques :+: (LocalVars :+: Reader DynFlags)))) sig m) => Map Loc LExpr -> Handler m a Source #
Replace holes in an AST whenever an expression with the corresponding source span can be found in the given list.
evacPats :: forall a m sig. (Has (Fill :+: State InScope) sig m, Data a) => Handler m a Source #
evacuate !s in pattern and collect all the names it binds
addStmts :: forall sig m. Has (PsErrors :+: (HoleFills :+: (Uniques :+: (LocalVars :+: Reader DynFlags)))) sig m => Handler m [ExprLStmt GhcPs] Source #
Find all !s in the given statements and combine the resulting bind statements into lists, with the original statements being the last one in each list - then concatenate these lists
type LocalVars = Reader InScope :+: Writer OccSet Source #
We keep track of variables that are bound in lambdas, cases, etc., since these are variables that will not be accessible in the surrounding 'do'-block, and must therefore not be used. The Reader is used to find out what local variables are in scope, the Writer is used to inform callers which local variables have been bound.
type Fill = PsErrors :+: (Writer (DList BindStmt) :+: (HoleFills :+: (Uniques :+: (LocalVars :+: Reader DynFlags)))) Source #
bindStmtExpr :: BindStmt -> LExpr Source #
bindStmtSpan :: BindStmt -> SrcSpan Source #
bangVar :: Has (Uniques :+: Reader DynFlags) sig m => LExpr -> Loc -> m RdrName Source #
Use the !'d expression if it's short enough, or else abbreviate with ...
We don't need to worry about shadowing other !'d expressions:
- For the user, we add line and column numbers to the name
- For the compiler, we use a unique instead of the name
tellLocalVar :: Has (Writer OccSet) sig m => OccName -> m () Source #