packages feed

monadloc-pp (empty) → 0.1

raw patch · 3 files changed

+132/−0 lines, 3 filesdep +basedep +filepathdep +haskell-src-extssetup-changed

Dependencies added: base, filepath, haskell-src-exts, monadloc, pretty, syb

Files

+ MonadLoc.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE PatternGuards #-}++import Data.Generics+import Data.List+import Language.Haskell.Exts.Annotated+import System.Environment+import System.FilePath+import Text.PrettyPrint++main :: IO ()+main = do+  args <- getArgs+  case args of++    (fn:inp:outp:_) -> do+         contents <- readFile inp+         let res = work fn contents+         writeFile outp res++    [] -> do+         contents <- getContents+         putStrLn $ work "INPUT" contents++    _ -> error "USAGE: MonadLoc expects the input from stdin and writes to stdout"++work :: FilePath -> String -> String+work fn contents =+         -- Invent a fake name for lhs files to avoid confusing haskell-src-exts+         let fn' = if takeExtension fn == ".lhs" then dropExtension fn <.> "hs" else fn++             Module l mhead opt imports decls =+               fromParseResult $+               parseFileContentsWithMode ourParseMode{parseFilename = fn'} contents+             mod'   = Module l mhead opt imports decls'+             mname  = case mhead of+                        Nothing -> ""+                        Just (ModuleHead _ mn _ _) -> prettyPrint mn+             decls' = map (annotateDecl mname) decls+         in prettyPrintStyleMode style{lineLength=100000} ourPrintMode mod'++ourParseMode :: ParseMode+ourParseMode = defaultParseMode { ignoreLinePragmas = False,+                                  extensions =+                                        [CPP+                                        ,MultiParamTypeClasses+                                        ,FunctionalDependencies+                                        ,FlexibleContexts+                                        ,FlexibleInstances+                                        ,ExplicitForall+                                        ,ExistentialQuantification+                                        ,PatternGuards+                                        ,ViewPatterns+                                        ,Arrows+                                        ,NamedFieldPuns+                                        ,DisambiguateRecordFields+                                        ,RecordWildCards+                                        ,StandaloneDeriving+                                        ,GeneralizedNewtypeDeriving+                                        ,ScopedTypeVariables+                                        ,PatternSignatures+                                        ,PackageImports+                                        ,QuasiQuotes+                                        ,PostfixOperators]+                                }++ourPrintMode :: PPHsMode+ourPrintMode = defaultMode { linePragmas = True }+++annotateDecl :: String -> Decl SrcSpanInfo -> Decl SrcSpanInfo+annotateDecl mname e@(FunBind _ (m:_)) = everywhere (mkT (annotateStatements (Just funName) mname)) e+  where+    funName = case m of+              Match _ name _ _ _ -> prettyPrint name+              InfixMatch _ _ name _ _ _ -> prettyPrint name++annotateDecl mname e@(PatBind _ (PVar _ fn) _ _ _) = everywhere (mkT (annotateStatements (Just $ prettyPrint fn) mname)) e+annotateDecl mname e = everywhere (mkT (annotateStatements Nothing mname)) e++annotateStatements :: Maybe String -> String -> Exp SrcSpanInfo -> Exp SrcSpanInfo+annotateStatements fun m (Do loc stmts)  = App loc (withLocCall fun m loc) (Paren loc $ Do  loc $ map (annotateStmt fun m) stmts)+annotateStatements fun m (MDo loc stmts) = App loc (withLocCall fun m loc) (Paren loc $ MDo loc $ map (annotateStmt fun m) stmts)+annotateStatements _   _ e = e++annotateStmt :: Maybe String ->  String -> Stmt SrcSpanInfo -> Stmt SrcSpanInfo+annotateStmt fun m (Generator loc pat exp) = Generator loc pat $ App loc (withLocCall fun m loc) (Paren loc exp)+annotateStmt fun m (Qualifier loc exp)     = Qualifier loc $ App loc (withLocCall fun m loc) (Paren loc exp)+annotateStmt fun m (RecStmt loc stmts)     = RecStmt loc $ map (annotateStmt fun m) stmts+annotateStmt _   _ stmt                    = stmt++withLocCall :: Maybe String -> String -> SrcSpanInfo -> Exp SrcSpanInfo+withLocCall fun m loc = App loc (Var loc withLoc) (Lit loc srclocLit)+  where+   withLoc   = Qual loc (ModuleName loc "Control.Monad.Loc") (Ident loc "withLoc")+   srclocLit = String loc (render locString) ""+   locStringTail = text m <> parens(text (fileName loc)) <> colon <+> parens (int (startLine loc) <> comma <+> int(startColumn loc))+   locString = case fun of+                 Nothing  -> locStringTail+                 Just fun -> text fun <> comma <+> locStringTail+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ monadloc-pp.cabal view
@@ -0,0 +1,30 @@+name: monadloc-pp+version: 0.1+Cabal-Version:  >= 1.6+build-type: Simple+license: PublicDomain+author: Pepe Iborra+maintainer: pepeiborra@gmail.com+homepage: http://github.com/pepeiborra/monadloc+synopsis: A preprocessor for generating monadic call traces+category: Control, Monads+stability: experimental+description:+  The package @monadloc@ defines a class for monads which can keep a monadic call trace.+  .+  * See the blog post <http://pepeiborra.posterous.com/monadic-stack-traces-that-make-a-lot-of-sense> for more information.+  .+  This package provides a preprocessor that inserts calls+  to "Control.Monad.Loc.withLoc" before every monadic statement in a module.+  To invoke the preprocessor, add the pragma @OPTIONS_GHC -F -pgmF MonadLoc@  at the top of your Haskell files  together with an import for the "Control.Monad.Loc" module+  .++Executable MonadLoc+   buildable: True+   build-depends: base >= 4 && < 5, pretty, syb, monadloc == 0.6, haskell-src-exts >= 1.3.0, filepath+   main-is: MonadLoc.hs+   ghc-options: -Wall -fno-warn-name-shadowing++source-repository head+  type:     git+  location: git://github.com/pepeiborra/monadloc-pp.git