{-# LANGUAGE TypeOperators #-} module Language.Haskell.Refact.Utils.LayoutUtils ( -- getLayoutFor -- , addDeclLayoutAfterSrcSpan showLTOne -- , openZipper ) where import qualified GHC as GHC import qualified Data.Generics as SYB import qualified GHC.SYB.Utils as SYB import Language.Haskell.Refact.Utils.GhcVersionSpecific import Language.Haskell.Refact.Utils.Layout import Language.Haskell.Refact.Utils.LayoutTypes import Language.Haskell.Refact.Utils.LocUtils import Language.Haskell.Refact.Utils.Monad import Language.Haskell.Refact.Utils.TokenUtils import Language.Haskell.Refact.Utils.TokenUtilsTypes import Language.Haskell.Refact.Utils.TypeSyn import Data.Tree import qualified Data.Tree.Zipper as Z import qualified Language.Haskell.Refact.Utils.TokenUtils as U import qualified Language.Haskell.Refact.Utils.TokenUtilsTypes as U -- --------------------------------------------------------------------- getLayoutFor :: GHC.SrcSpan -> TokenLayout -> LayoutTree getLayoutFor sspan (TL layout) = getLayoutFor' sspan layout getLayoutFor' :: GHC.SrcSpan -> LayoutTree -> LayoutTree -- getLayoutFor' sspan tl@(Leaf ss _ _) getLayoutFor' sspan tl@(Node (U.Entry ss _ _) []) | sspan == (fs ss) = tl | otherwise = error $ "getLayoutFor :" ++ (showGhc sspan) ++ " not in " ++ (showGhc tl) -- getLayoutFor' sspan tl@(Group ss _ subs) getLayoutFor' sspan tl@(Node (U.Entry ss _ []) subs) | sspan == (fs ss) = tl | null subs = error $ "getLayoutFor :" ++ (showGhc sspan) ++ " not in " ++ (showGhc tl) | length subs > 1 = error $ "getLayoutFor :" ++ (showGhc sspan) ++ " multiple in " ++ (showGhc tl) | otherwise = getLayoutFor' sspan sub where sub = getChildForSpan sspan subs -- --------------------------------------------------------------------- {- addDeclLayoutAfterSrcSpan :: (SYB.Data t) => LayoutTree -- ^TokenTree to be modified -> GHC.SrcSpan -- ^Preceding location for new tokens -> U.Positioning -> LayoutTree -- ^New tokens to be added -> GHC.Located t -- ^Declaration the tokens belong to, to be synced -> (TokenLayout, GHC.SrcSpan,GHC.Located t) -- ^ updated TokenTree ,SrcSpan location for -- the new tokens in the TokenTree, and -- updated AST element addDeclLayoutAfterSrcSpan tl oldSpan pos layout t = (tl'',newSpan,t') where (tl',newSpan) = addLayoutAfterSrcSpan tl oldSpan pos layout (t',tl'') = syncAST t newSpan tl' -} -- --------------------------------------------------------------------- {- -- |Add new tokens after the given SrcSpan, constructing a new SrcSpan -- in the process addLayoutAfterSrcSpan :: LayoutTree -- ^TokenTree to be modified -> GHC.SrcSpan -- ^Preceding location for new tokens -> U.Positioning -> LayoutTree -- ^New tokens to be added -> (LayoutTree, GHC.SrcSpan) -- ^ updated TokenTree and SrcSpan location for -- the new tokens in the TokenTree addLayoutAfterSrcSpan lt oldSpan pos layout = (lt',newSpan') where tree = getSrcSpanFor lt oldSpan toks'' = placeLayoutForSpan lt oldSpan tree pos layout (startPos,endPos) = U.nonCommentSpan toks'' newSpan = U.posToSrcSpanTok mkZeroToken (startPos,endPos) (lt',newSpan') = addNewSrcSpanAndToksAfter lt oldSpan newSpan pos layout -} -- --------------------------------------------------------------------- -- getSrcSpanFor = error "getSrcSpanFor undefined" -- placeLayoutForSpan = undefined -- addNewSrcSpanAndToksAfter = undefined -- --------------------------------------------------------------------- {- openZipperToSpan :: GHC.SrcSpan -> LayoutTree -> Top :>> LayoutTree openZipperToSpan sspan lay = r where -- r = toZipper lay r = zipper lay -} {- openZipper :: GHC.SrcSpan -> Top :>> LayoutTree -> Top :>> LayoutTree openZipper sspan z | getLoc (view focus z) == sspan = z | isLeaf (view focus z) = error $ "openZipperToSpan not found " ++ showGhc sspan ++ ":" ++ showLTOne (view focus z) | otherwise = openZipper sspan z' where (Group _ _ subs) = view focus z z' = zipper (getChildForSpan sspan subs) -} {- openZipper :: GHC.SrcSpan -> Z.TreePos Z.Full Label -> Z.TreePos Z.Full Label openZipper sspan z | getLoc (Z.tree z) == sspan = z | otherwise = openZipper sspan child where child = ghead "openZipper" $ filter (GHC.isSubspanOf sspan . getLoc . Z.tree) childrenAsZ childrenAsZ = getChildrenAsZ z -} -- --------------------------------------------------------------------- {- getChildrenAsZ :: Z.TreePos Z.Full a -> [Z.TreePos Z.Full a] getChildrenAsZ z = go [] (Z.firstChild z) where go acc Nothing = acc go acc (Just zz) = go (acc ++ [zz]) (Z.next zz) -} -- --------------------------------------------------------------------- -- TODO: need to make ForestLine version of isSubspanof getChildForSpan :: GHC.SrcSpan -> [LayoutTree] -> LayoutTree getChildForSpan sspan subs = sub where sub = ghead "getChildForSpan" $ map snd $ filter (GHC.isSubspanOf sspan . fst) $ map (\t -> (fs $ getLoc t,t)) subs -- --------------------------------------------------------------------- showLTOne :: LayoutTree -> String -- showLTOne (Leaf ss lay _toks) = "(Leaf " ++ (showGhc ss) ++ " " ++ (show lay) ++ " " ++ "toks)" -- showLTOne (Group ss lay subs) = "(Group " ++ (showGhc ss) ++ " " ++ (show lay) ++ " " ++ showGhc (map getLoc subs) ++ ")" showLTOne (Node (U.Entry ss lay _toks) []) = "(Leaf " ++ (showGhc ss) ++ " " ++ (show lay) ++ " " ++ "toks)" showLTOne (Node (U.Entry ss lay []) subs) = "(Group " ++ (showGhc ss) ++ " " ++ (show lay) ++ " " ++ showGhc (map getLoc subs) ++ ")" -- --------------------------------------------------------------------- isLeaf :: LayoutTree -> Bool isLeaf (Node _ []) = True isLeaf _ = False -- --------------------------------------------------------------------- -- experiments