1+ {-# LANGUAGE ScopedTypeVariables #-}
2+ {-# LANGUAGE QuasiQuotes #-}
13{-# LANGUAGE OverloadedStrings #-}
24{-# LANGUAGE PatternGuards #-}
35{-# LANGUAGE RecordWildCards #-}
6+ {-# LANGUAGE ExtendedDefaultRules #-}
47{-# LANGUAGE ExistentialQuantification #-}
58
69{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-missing-signatures -fno-warn-type-defaults #-}
1114module Main (main ) where
1215
1316import Control.Applicative
17+ import Control.Applicative.QQ.Idiom
1418import Data.Data
1519import Data.List
1620import Data.Maybe
1721import Data.Text (Text )
1822import qualified Data.Text as T
1923import Descriptive
2024import Descriptive.Options
25+ import GHC.Tuple
2126import Language.Haskell.Exts.Annotated
2227import System.Environment
2328
@@ -58,7 +63,7 @@ data ParseType = Decl | Stmt
5863
5964-- | Command line options.
6065options :: Monad m => Consumer [Text ] (Option () ) m (Action ,ParseType ,[Extension ])
61- options = (,,) <$> action <*> typ <*> exts
66+ options = [ i | (,,) action typ exts|]
6267 where action =
6368 constant " parse" " Parse and spit out spans" Parse <|>
6469 constant " check" " Just check the syntax" Check
@@ -82,15 +87,16 @@ outputWith action typ exts code =
8287-- | Output AST info for the given Haskell code.
8388output :: Action -> Parser -> [Extension ] -> String -> IO ()
8489output action parser exts code =
85- case parser parseMode {extensions = exts} code of
90+ case parser mode code of
8691 ParseFailed _ e -> error e
8792 ParseOk (D ast) ->
8893 case action of
8994 Check -> return ()
9095 Parse ->
9196 putStrLn (" [" ++
92- concat (genHSE ast) ++
97+ concat (genHSE mode ast) ++
9398 " ]" )
99+ where mode = parseMode {extensions = exts}
94100
95101-- | An umbrella parser to parse:
96102--
@@ -126,19 +132,20 @@ parseMode =
126132 ,fixities = Nothing }
127133
128134-- | Generate a list of spans from the HSE AST.
129- genHSE :: Data a => a -> [String ]
130- genHSE x =
135+ genHSE :: Data a => ParseMode -> a -> [String ]
136+ genHSE mode x =
131137 case gmapQ D x of
132138 zs@ (D y: ys) ->
133139 case cast y of
134140 Just s ->
135141 spanHSE (show (show (typeOf x)))
136142 (showConstr (toConstr x))
137143 (srcInfoSpan s) :
138- concatMap (\ (i,D d) -> pre x i ++ genHSE d)
139- (zip [0 .. ] ys)
144+ concatMap (\ (i,D d) -> pre x i ++ genHSE mode d)
145+ (zip [0 .. ] ys) ++
146+ post mode x
140147 _ ->
141- concatMap (\ (D d) -> genHSE d) zs
148+ concatMap (\ (D d) -> genHSE mode d) zs
142149 _ -> []
143150
144151-- | Pre-children tweaks for a given parent at index i.
@@ -170,6 +177,42 @@ pre x i =
170177 ,Just (IRule _ _ _ (IHCon (SrcSpanInfo end _) _)) <- [listToMaybe (reverse ds)]]
171178 _ -> []
172179
180+ -- | Post-node tweaks for a parent, e.g. adding more children.
181+ post :: (Typeable a ) => ParseMode -> a -> [String ]
182+ post mode x =
183+ case cast x of
184+ Just (QuasiQuote (base :: SrcSpanInfo ) qname content) ->
185+ case parseExpWithMode mode content of
186+ ParseOk ex -> genHSE mode (fmap (redelta qname base) ex)
187+ ParseFailed _ e -> error e
188+ _ -> []
189+
190+ -- | Apply a delta to the positions in the given span from the base.
191+ redelta :: String -> SrcSpanInfo -> SrcSpanInfo -> SrcSpanInfo
192+ redelta qname base (SrcSpanInfo (SrcSpan fp sl sc el ec) pts) =
193+ SrcSpanInfo
194+ (if sl == 1
195+ then SrcSpan fp
196+ (sl + lineOffset)
197+ (sc + columnOffset)
198+ (el + lineOffset)
199+ (if el == sl
200+ then ec + columnOffset
201+ else ec)
202+ else SrcSpan fp
203+ (sl + lineOffset)
204+ sc
205+ (el + lineOffset)
206+ ec)
207+ pts
208+ where lineOffset = sl' - 1
209+ columnOffset =
210+ sc' - 1 +
211+ length (" [" :: String ) +
212+ length qname +
213+ length (" |" :: String )
214+ (SrcSpanInfo (SrcSpan _ sl' sc' _ _) _) = base
215+
173216-- | Generate a span from a HSE SrcSpan.
174217spanHSE :: String -> String -> SrcSpan -> String
175218spanHSE typ cons SrcSpan {.. } = " [" ++ spanContent ++ " ]"
0 commit comments