-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Utilities to tie up tokens to an AST -- -- This library is currently experimental. -- -- The GHC part is solid, since it has been migrated from HaRe. -- -- The haskell-src-exts one is still in progress -- -- This package provides a set of data structures to manage the tie-up -- between a Haskell AST and the underlying tokens, such that it -- explicitly captures the Haskell layout rules and original formatting. -- As a result changes can be made to the AST and the tokens will be -- updated so that the source file can be recreated with only the updated -- parts changed. This makes it easier to write Haskell source code -- modification programmes. @package haskell-token-utils @version 0.0.0.4 module Language.Haskell.TokenUtils.Types -- | An entry in the data structure for a particular srcspan. data Entry a -- | Entry has * the source span contained in this Node * how the -- sub-elements nest * the tokens for the SrcSpan if subtree is empty Entry :: !ForestSpan -> !Layout -> ![a] -> Entry a -- | Deleted has * the source span has been deleted * prior gap in lines * -- the gap between this span end and the start of the next in the fringe -- of the tree. Deleted :: !ForestSpan -> !RowOffset -> !SimpPos -> Entry a data TokenCache a TK :: !(Map TreeId (Tree (Entry a))) -> !TreeId -> TokenCache a tkCache :: TokenCache a -> !(Map TreeId (Tree (Entry a))) tkLastTreeId :: TokenCache a -> !TreeId data TreeId TId :: !Int -> TreeId -- | Identifies the tree carrying the main tokens, not any work in progress -- or deleted ones mainTid :: TreeId -- | Match a SrcSpan, using a ForestLine as the marker type ForestSpan = (ForestPos, ForestPos) type ForestPos = (ForestLine, Int) data ForestLine ForestLine :: !Bool -> !Int -> !Int -> !Int -> ForestLine -- | The length of the span may have changed due to updated tokens. flSpanLengthChanged :: ForestLine -> !Bool flTreeSelector :: ForestLine -> !Int flInsertVersion :: ForestLine -> !Int flLine :: ForestLine -> !Int type RowOffset = Int type ColOffset = Int type Row = Int type Col = Int type SimpPos = (Int, Int) type SimpSpan = (SimpPos, SimpPos) data Layout -- | Initial offset from token before the stacked list of items, the (r,c) -- of the first non-comment token, the (r,c) of the end of the last -- non-comment token in the stacked list to be able to calculate the -- (RowOffset,ColOffset) between the last token and the start of the next -- item. Above :: EndOffset -> (Row, Col) -> (Row, Col) -> EndOffset -> Layout NoChange :: Layout data EndOffset None :: EndOffset SameLine :: ColOffset -> EndOffset FromAlignCol :: (RowOffset, ColOffset) -> EndOffset class Outputable a ppr :: Outputable a => a -> Doc data TokenLayout a type LayoutTree a = Tree (Entry a) -- | Extract an encoded ForestLine from a GHC line ghcLineToForestLine :: Int -> ForestLine forestLineToGhcLine :: ForestLine -> Int forestLenChangedMask :: Int -- | The IsToken class captures the different token type in use. For GHC it -- represents the type returned by getRichTokenStream, namely -- [(GHC.Located GHC.Token, String)] For haskell-src-exts this is the -- reult of lexTokenStream, namely `[HSE.Loc HSE.Token]` class (Show a, HasLoc a) => IsToken a tokenLen :: IsToken a => a -> Int isComment :: IsToken a => a -> Bool isEmpty :: IsToken a => a -> Bool mkZeroToken :: IsToken a => a isDo :: IsToken a => a -> Bool isElse :: IsToken a => a -> Bool isIn :: IsToken a => a -> Bool isLet :: IsToken a => a -> Bool isOf :: IsToken a => a -> Bool isThen :: IsToken a => a -> Bool isWhere :: IsToken a => a -> Bool tokenToString :: IsToken a => a -> String showTokenStream :: IsToken a => [a] -> String lexStringToTokens :: IsToken a => SimpSpan -> String -> [a] markToken :: IsToken a => a -> a isMarked :: IsToken a => a -> Bool notWhiteSpace :: IsToken a => a -> Bool isWhiteSpaceOrIgnored :: IsToken a => a -> Bool isIgnored :: IsToken a => a -> Bool -- | Tokens that are ignored when determining the first non-comment token -- in a span isIgnoredNonComment :: IsToken a => a -> Bool isWhereOrLet :: IsToken a => a -> Bool showFriendlyToks :: IsToken a => [a] -> String class HasLoc a where getSpan a = (getLoc a, getLocEnd a) getLoc :: HasLoc a => a -> SimpPos getLocEnd :: HasLoc a => a -> SimpPos getSpan :: HasLoc a => a -> SimpSpan putSpan :: HasLoc a => a -> SimpSpan -> a class Allocatable b a allocTokens :: (Allocatable b a, IsToken a) => b -> [a] -> LayoutTree a instance Show EndOffset instance Eq EndOffset instance Show Layout instance Eq Layout instance Show a => Show (Entry a) instance Eq TreeId instance Ord TreeId instance Show TreeId instance Ord ForestLine instance Show ForestLine instance Eq ForestLine module Language.Haskell.TokenUtils.Utils -- | Split the token stream into three parts: the tokens before the -- startPos, the tokens between startPos and endPos, and the tokens after -- endPos. Note: The startPos and endPos refer to the startPos of a token -- only. So a single token will have the same startPos and endPos NO^^^^ splitToks :: IsToken a => (SimpPos, SimpPos) -> [a] -> ([a], [a], [a]) ghead :: String -> [a] -> a glast :: String -> [a] -> a gtail :: String -> [a] -> [a] gfromJust :: [Char] -> Maybe a -> a addEndOffsets :: IsToken a => LayoutTree a -> [a] -> LayoutTree a calcLastTokenPos :: IsToken a => [a] -> (Int, Int) makeOffset :: RowOffset -> ColOffset -> EndOffset makeLeaf :: IsToken a => SimpSpan -> Layout -> [a] -> LayoutTree a makeLeafFromToks :: IsToken a => [a] -> [LayoutTree a] -- | Split the given tokens to include the comments belonging to the span. splitToksIncComments :: IsToken a => (SimpPos, SimpPos) -> [a] -> ([a], [a], [a]) makeGroup :: IsToken a => [LayoutTree a] -> LayoutTree a makeGroupLayout :: IsToken a => Layout -> [LayoutTree a] -> LayoutTree a makeSpanFromTrees :: [LayoutTree a] -> ForestSpan mkGroup :: IsToken a => SimpSpan -> Layout -> [LayoutTree a] -> LayoutTree a subTreeOnly :: IsToken a => [LayoutTree a] -> [LayoutTree a] -- | Split the given tokens into the ones that occur prior to the start of -- the list and ones that occur after splitToksForList :: (IsToken a, HasLoc b) => [b] -> [a] -> ([a], [a], [a]) placeAbove :: IsToken a => EndOffset -> (Row, Col) -> (Row, Col) -> [LayoutTree a] -> LayoutTree a allocList :: (IsToken a, HasLoc b) => [b] -> [a] -> (b -> [a] -> [LayoutTree a]) -> [LayoutTree a] strip :: IsToken a => [LayoutTree a] -> [LayoutTree a] -- | Get the start&end location of t in the token stream, then extend -- the start and end location to cover the preceding and following -- comments. startEndLocIncComments' :: IsToken a => [a] -> (SimpPos, SimpPos) -> (SimpPos, SimpPos) simpPosToForestSpan :: (SimpPos, SimpPos) -> ForestSpan ss2f :: (SimpPos, SimpPos) -> ForestSpan -- | Strip out the version markers forestSpanToSimpPos :: ForestSpan -> (SimpPos, SimpPos) f2ss :: ForestSpan -> (SimpPos, SimpPos) treeIdFromForestSpan :: ForestSpan -> TreeId -- | Gets the version numbers forestSpanVersions :: ForestSpan -> (Int, Int) -- | Gets the AST tree numbers forestSpanAstVersions :: ForestSpan -> (Int, Int) -- | Gets the SpanLengthChanged flags forestSpanLenChangedFlags :: ForestSpan -> (Bool, Bool) -- | Checks if the version is zero in both positions forestSpanVersionNotSet :: ForestSpan -> Bool -- | Checks if the version is non-zero forestPosVersionSet :: ForestPos -> Bool -- | Checks if the AST version is non-zero forestPosAstVersionSet :: ForestPos -> Bool -- | Checks if the version is zero forestPosVersionNotSet :: ForestPos -> Bool forestSpanLenChanged :: ForestSpan -> Bool forestPosLenChanged :: ForestPos -> Bool -- | Puts a TreeId into a forestSpan treeIdIntoForestSpan :: TreeId -> ForestSpan -> ForestSpan -- | Does the first span contain the second? Takes cognisance of the -- various flags a ForestSpan can have. NOTE: This function relies on the -- Eq instance for ForestLine spanContains :: ForestSpan -> ForestSpan -> Bool insertVersionsInForestSpan :: Int -> Int -> ForestSpan -> ForestSpan insertLenChangedInForestSpan :: Bool -> ForestSpan -> ForestSpan forestSpanFromEntry :: Entry a -> ForestSpan putForestSpanInEntry :: Entry a -> ForestSpan -> Entry a -- | Checks if the version is non-zero in either position forestSpanVersionSet :: ForestSpan -> Bool -- | Get the start and end position of a Tree treeStartEnd :: Tree Entry -- -> (SimpPos,SimpPos) treeStartEnd (Node (Entry sspan _) _) = -- (getGhcLoc sspan,getGhcLocEnd sspan) treeStartEnd :: Tree (Entry a) -> ForestSpan groupTokensByLine :: IsToken a => [a] -> [[a]] tokenRow :: IsToken a => a -> Int tokenCol :: IsToken a => a -> Int tokenColEnd :: IsToken a => a -> Int tokenPos :: IsToken a => a -> SimpPos tokenPosEnd :: IsToken a => a -> SimpPos -- | Shift the whole token by the given offset increaseSrcSpan :: IsToken a => SimpPos -> a -> a srcPosToSimpPos :: (Int, Int) -> (Int, Int) -- | Add a constant line and column offset to a span of tokens addOffsetToToks :: IsToken a => SimpPos -> [a] -> [a] decorate :: IsToken a => LayoutTree a -> [a] -> LayoutTree a -- | ForestSpan version of GHC combineSrcSpans combineSpans :: ForestSpan -> ForestSpan -> ForestSpan -- | Extract the start and end position of a span, without any leading or -- trailing comments nonCommentSpan :: IsToken a => [a] -> (SimpPos, SimpPos) getStartLoc :: SimpSpan -> SimpPos getEndLoc :: SimpSpan -> SimpPos -- | Neat 2-dimensional drawing of a tree. drawTreeEntry :: Tree (Entry a) -> String -- | Neat 2-dimensional drawing of a forest. drawForestEntry :: Forest (Entry a) -> String showLayout :: Layout -> String drawTreeCompact :: Tree (Entry a) -> String drawTreeWithToks :: IsToken a => Tree (Entry a) -> String showForestSpan :: ForestSpan -> String -- | Call drawTreeEntry on the entire token cache drawTokenCache :: IsToken a => TokenCache a -> String -- | Call drawTreeEntry on the entire token cache drawTokenCacheDetailed :: IsToken a => TokenCache a -> String -- | Split a set of comment tokens into the ones that belong with the -- startLine and those that belong with the endLine divideComments :: IsToken a => Int -> Int -> [a] -> ([a], [a]) instance HasLoc ForestSpan instance HasLoc (Entry a) instance IsToken a => Eq (Entry a) instance IsToken t => Ord (LayoutTree t) module Language.Haskell.TokenUtils.TokenUtils -- | The primary data structure is the TokenCache. This holds the -- evolving forest of modified LayoutTrees. Each concrete -- implementation should provide a function to generate a -- LayoutTree from its specific AST and tokens. initTokenCacheLayout :: IsToken a => Tree (Entry a) -> TokenCache a -- | Make a tree representing a particular set of tokens mkTreeFromTokens :: IsToken a => [a] -> Tree (Entry a) -- | Make a tree representing a particular set of tokens mkTreeFromSpanTokens :: IsToken a => ForestSpan -> [a] -> Tree (Entry a) -- | How new SrcSpans should be inserted in the Token tree, relative to the -- prior span data Positioning -- | Only a single space between the end of the prior span and the new one PlaceAdjacent :: Positioning -- | Start at the specified line and col PlaceAbsolute :: !Int -> !Int -> Positioning -- | Line offset and absolute Col. Mainly for forcing start at left margin, -- number of lines to add at the end PlaceAbsCol :: !Int -> !Int -> !Int -> Positioning -- | Line and Col offset for start, num lines to add at the end relative to -- the indent level of the prior span PlaceOffset :: !Int -> !Int -> !Int -> Positioning -- | Line and Col offset for start, num lines to add at the end relative to -- the indent level of the prior line PlaceIndent :: !Int -> !Int -> !Int -> Positioning -- | Keep track of when tokens are reversed, to avoid confusion data ReversedToks a RT :: [a] -> ReversedToks a putToksInCache :: IsToken a => TokenCache a -> SimpSpan -> [a] -> (TokenCache a, SimpSpan) replaceTokenInCache :: IsToken a => TokenCache a -> SimpSpan -> a -> TokenCache a removeToksFromCache :: IsToken a => TokenCache a -> SimpSpan -> TokenCache a getTokensFromCache :: IsToken a => Bool -> TokenCache a -> SimpSpan -> (TokenCache a, [a]) getTokensNoIntrosFromCache :: IsToken a => Bool -> TokenCache a -> SimpSpan -> (TokenCache a, [a]) getTokensBeforeFromCache :: IsToken a => TokenCache a -> SimpSpan -> (TokenCache a, ReversedToks a) addTokensAfterSpanInCache :: IsToken a => TokenCache a -> SimpSpan -> Positioning -> [a] -> (TokenCache a, SimpSpan) -- | Replace the tokens for a given SrcSpan with new ones. The SrcSpan will -- be inserted into the tree if it is not already there. If the SrcSpan -- changes size, replace the SrcSpan with a new one (marked), and return -- it, as well as the old one TODO: What about trailing comments? -- Preserve or replace? updateTokensForSrcSpan :: IsToken a => Tree (Entry a) -> SimpSpan -> [a] -> (Tree (Entry a), SimpSpan, Tree (Entry a)) -- | Replace a single token in a token tree, without changing the structure -- of the tree NOTE: the GHC.SrcSpan may have been used to select the -- appropriate forest in the first place, and is required to select the -- correct span in the tree, due to the ForestLine annotations that may -- be present replaceTokenForSrcSpan :: IsToken a => Tree (Entry a) -> SimpSpan -> a -> Tree (Entry a) -- | Retrieve a path to the tree containing a ForestSpan from the forest, -- inserting it if not already present getSrcSpanFor :: IsToken a => Tree (Entry a) -> ForestSpan -> (Tree (Entry a), Tree (Entry a)) -- | indent the tree and tokens by the given offset, and sync the AST to -- the tree too. indentDeclToks :: (IsToken a, HasLoc t) => (t -> ForestSpan -> t) -> t -> Tree (Entry a) -> Int -> (t, Tree (Entry a)) -- | Add new tokens after the given SrcSpan, constructing a new SrcSpan in -- the process addToksAfterSrcSpan :: IsToken a => Tree (Entry a) -> SimpSpan -> Positioning -> [a] -> (Tree (Entry a), SimpSpan) addOffsetToSpan :: (Int, Int) -> SimpSpan -> SimpSpan -- | Place the new tokens so that they are positioned correctly relative to -- the previous tokens reIndentToks :: IsToken a => Positioning -> [a] -> [a] -> [a] -- | Convert a string into a set of Haskell tokens. It has default position -- and offset, since it will be stitched into place in TokenUtils basicTokenise :: IsToken a => String -> [a] -- | Convert a string into a set of Haskell tokens, following the given -- position, with each line indented by a given column offset if required -- TODO: replace 'colOffset withFirstLineIndent' with a Maybe Int ++AZ++ tokenise :: IsToken a => SimpSpan -> Int -> Bool -> String -> [a] -- | Check the invariant for the token cache. Returns list of any errors -- found. Invariants: 1. For each tree, either the rootLabel has a -- SrcSpan only, or the subForest /= []. 2a. The trees making up the -- subForest of a given node fully include the parent SrcSpan. i.e. the -- leaves contain all the tokens for a given SrcSpan. 2b. The subForest -- is in SrcSpan order 3. A given SrcSpan can only appear (or be -- included) in a single tree of the forest. 4. The parent link for all -- sub-trees does exist, and actually points to the parent. 5. There are -- no nullForestSpan entries in the tree NOTE: the tokens may extend -- before or after the SrcSpan, due to comments only NOTE2: this will -- have to be revisited when edits to the tokens are made invariant :: IsToken a => Tree (Entry a) -> [String] reverseToks :: IsToken a => [a] -> ReversedToks a unReverseToks :: IsToken a => ReversedToks a -> [a] reversedToks :: IsToken a => ReversedToks a -> [a] -- | Retrieve all the tokens at the leaves of the tree, in order. No -- adjustments are made to address gaps or re-alignment of the tokens retrieveTokensInterim :: IsToken a => Tree (Entry a) -> [a] -- | Get the (possible cached) tokens for a given source span, and cache -- their being fetched. NOTE: The SrcSpan may be one introduced by HaRe, -- rather than GHC. getTokensForNoIntros :: IsToken a => Bool -> Tree (Entry a) -> SimpSpan -> (Tree (Entry a), [a]) -- | Get the (possible cached) tokens for a given source span, and cache -- their being fetched. NOTE: The SrcSpan may be one introduced by HaRe, -- rather than GHC. getTokensFor :: IsToken a => Bool -> Tree (Entry a) -> SimpSpan -> (Tree (Entry a), [a]) -- | Get the tokens preceding a given SrcSpan getTokensBefore :: IsToken a => Tree (Entry a) -> SimpSpan -> (Tree (Entry a), ReversedToks a) reAlignMarked :: IsToken a => [a] -> [a] splitOnNewLn :: IsToken a => [a] -> ([a], [a]) -- | Get the indent of the line before, taking into account in-line -- 'where', 'let', 'in' and 'do' tokens getIndentOffset :: IsToken a => [a] -> SimpPos -> Int newLnToken :: IsToken a => a -> a -- | Get the start&end location of t in the token stream, then extend -- the start and end location to cover the preceding and following -- comments. startEndLocIncComments' :: IsToken a => [a] -> (SimpPos, SimpPos) -> (SimpPos, SimpPos) -- | Strip out the version markers forestSpanToGhcPos :: ForestSpan -> (SimpPos, SimpPos) nullForestSpan :: ForestSpan nullForestPos :: ForestPos simpPosToForestSpan :: (SimpPos, SimpPos) -> ForestSpan showTree :: IsToken a => Tree (Entry a) -> String showToks :: IsToken a => [a] -> String -- | Add a new SrcSpan and Tokens after a given one in the token stream and -- forest. This will be given a unique SrcSpan in return, which -- specifically indexes into the forest. addNewSrcSpanAndToksAfter :: IsToken a => Tree (Entry a) -> SimpSpan -> SimpSpan -> Positioning -> [a] -> (Tree (Entry a), SimpSpan) -- | Open a zipper so that its focus has the given SrcSpan in its subtree, -- or the location where the SrcSpan should go, if it is not in the tree openZipperToSpan :: IsToken a => ForestSpan -> TreePos Full (Entry a) -> TreePos Full (Entry a) -- | Open a zipper to a SrcSpan that has been added in the tree, and thus -- does not necessarily fall in the logical hierarchy of the tree openZipperToSpanAdded :: IsToken a => ForestSpan -> TreePos Full (Entry a) -> TreePos Full (Entry a) -- | Starting from a point in the zipper, retrieve all tokens backwards -- until the line changes for a non-comment/non-empty token or beginning -- of file. retrievePrevLineToks :: IsToken a => TreePos Full (Entry a) -> ReversedToks a limitPrevToks :: IsToken a => ReversedToks a -> SimpSpan -> ReversedToks a -- | Insert a ForestSpan into the forest, if it is not there already. -- Assumes the forest was populated with the tokens containing the -- ForestSpan already insertSrcSpan :: IsToken a => Tree (Entry a) -> ForestSpan -> Tree (Entry a) insertLenChangedInSrcSpan :: Bool -> Bool -> SimpSpan -> SimpSpan insertVersionsInSrcSpan :: Int -> Int -> SimpSpan -> SimpSpan -- | Removes a ForestSpan and its tokens from the forest. removeSrcSpan :: IsToken a => Tree (Entry a) -> ForestSpan -> (Tree (Entry a), Tree (Entry a)) -- | True if the start of the second param lies in the span of the first containsStart :: ForestSpan -> ForestSpan -> Bool -- | True if the start of the second param lies before the first, and ends -- after or on the second containsMiddle :: ForestSpan -> ForestSpan -> Bool -- | True if the end of the second param lies in the span of the first containsEnd :: ForestSpan -> ForestSpan -> Bool -- | Split a given tree into a possibly empty part that lies before the -- srcspan, the part that is wholly included in the srcspan and the part -- the lies outside of it at the end. splitSubtree :: IsToken a => Tree (Entry a) -> ForestSpan -> ([Tree (Entry a)], [Tree (Entry a)], [Tree (Entry a)]) -- | Insert a new node after the designated one in the tree insertNodeAfter :: IsToken a => Tree (Entry a) -> Tree (Entry a) -> Tree (Entry a) -> Tree (Entry a) splitSubToks :: IsToken a => Tree (Entry a) -> (ForestPos, ForestPos) -> ([Tree (Entry a)], [Tree (Entry a)], [Tree (Entry a)]) placeToksForSpan :: IsToken a => Tree (Entry a) -> SimpSpan -> Tree (Entry a) -> Positioning -> [a] -> [a] -- | Some tokens are marked if they belong to identifiers which have been -- renamed. When the renaming takes place, no layout adjustment is done. -- This function adjusts the spacing for the rest of the line to match as -- far as possible the original spacing, except for the name change. reAlignOneLine :: IsToken a => [a] -> [a] -- | For a span about to be deleted, calculate the gap between the end of -- the span being deleted and the start of the next one, at a token -- level. calcEndGap :: IsToken a => Tree (Entry a) -> ForestSpan -> SimpPos getTreeSpansAsList :: IsToken a => Tree (Entry a) -> [(Int, ForestSpan)] -- | Open a zipper so that its focus has the given SrcSpan in its subtree, -- or the location where the SrcSpan should go, if it is not in the tree openZipperToSpanOrig :: IsToken a => ForestSpan -> TreePos Full (Entry a) -> TreePos Full (Entry a) -- | Replace a single token in the token stream by a new token, without -- adjusting the layout. Note1: does not re-align, else other later -- replacements may fail. Note2: must keep original end col, to know what -- the inter-token gap was when re-aligning replaceTokNoReAlign :: IsToken a => [a] -> SimpPos -> a -> [a] -- | Initialise a TokenCache from tokens only. Does not generate a -- layout-aware tree due to missing AST -- | Deprecated: residual from tests initTokenCache :: IsToken a => [a] -> TokenCache a getTreeFromCache :: IsToken a => SimpSpan -> TokenCache a -> Tree (Entry a) replaceTreeInCache :: IsToken a => SimpSpan -> Tree (Entry a) -> TokenCache a -> TokenCache a -- | Transfer the location information from the first param to the second matchTokenPos :: IsToken a => a -> a -> a instance Show a => Show (ReversedToks a) instance Show Positioning module Language.Haskell.TokenUtils.HSE.Layout -- | Load a file using 'haskell-src-exts' to provide both the AST and -- tokens loadFile :: FilePath -> IO (ParseResult (Module SrcSpanInfo, [Loc TuToken])) -- | Load a file using 'haskell-src-exts' to provide both the AST and -- tokens, using a custom loading mode allowing extensions to be enabled loadFileWithMode :: ParseMode -> FilePath -> IO (ParseResult (Module SrcSpanInfo, [Loc TuToken])) templateHaskellMode :: ParseMode data TuToken T :: Token -> TuToken C :: Comment -> TuToken s2ss :: SimpSpan -> SrcSpan ss2s :: SrcSpan -> SimpSpan instance Show TuToken instance Eq TuToken instance Monoid Layout instance Allocatable (Module SrcSpanInfo) (Loc TuToken) instance HasLoc SrcSpan instance HasLoc (Loc a) instance IsToken (Loc TuToken) module Language.Haskell.TokenUtils.Layout retrieveTokens :: IsToken a => LayoutTree a -> [a] module Language.Haskell.TokenUtils.DualTree renderLayoutTree :: IsToken a => LayoutTree a -> String layoutTreeToSourceTree :: IsToken a => LayoutTree a -> SourceTree a retrieveLinesFromLayoutTree :: IsToken a => LayoutTree a -> [Line a] retrieveLines :: IsToken a => SourceTree a -> [Line a] renderLines :: IsToken a => [Line a] -> String renderSourceTree :: IsToken a => SourceTree a -> String -- | The main data structure for this module type SourceTree a = DUALTree Transformation (Up a) Annot (Prim a) data Line a Line :: Row -> Col -> RowOffset -> Source -> LineOpt -> [a] -> Line a data Source SOriginal :: Source SAdded :: Source SWasAdded :: Source renderLinesFromLayoutTree :: IsToken a => LayoutTree a -> String data Alignment ANone :: Alignment AVertical :: Alignment data Annot Ann :: String -> Annot ADeleted :: ForestSpan -> RowOffset -> SimpPos -> Annot ASubtree :: ForestSpan -> Annot data DeletedSpan DeletedSpan :: SimpSpan -> RowOffset -> SimpPos -> DeletedSpan data LineOpt ONone :: LineOpt -- | This line needs to be grouped with the next in terms of layout, so any -- column offsets need to be propagated OGroup :: LineOpt data Prim a PToks :: [a] -> Prim a PDeleted :: ForestSpan -> RowOffset -> SimpPos -> Prim a data Transformation TAbove :: ColOffset -> EndOffset -> (Row, Col) -> (Row, Col) -> EndOffset -> Transformation -- | The value that bubbles up. This is the Span occupied by the subtree, -- together with a string representation of the subtree. The origin of -- the string is the start of the span. data Up a Up :: DtSimpSpan -> Alignment -> (NonEmpty (Line a)) -> [DeletedSpan] -> Up a UDeleted :: [DeletedSpan] -> Up a instance Show DeletedSpan instance Eq DeletedSpan instance Show Transformation instance Eq DtSimpSpan instance Show DtSimpSpan instance Show Alignment instance Eq Alignment instance Show Source instance Eq Source instance Show LineOpt instance Eq LineOpt instance IsToken a => Show (Up a) instance Show Annot instance Show a => Show (Prim a) instance Action Transformation (Up a) instance Semigroup Transformation instance IsToken a => Semigroup (Up a) instance Semigroup DtSimpSpan instance IsToken a => Show (Line a) instance Outputable DtSimpSpan module Language.Haskell.TokenUtils.Pretty showPpr :: Outputable a => a -> String instance (Outputable a, Outputable b) => Outputable (a, b) instance Outputable a => Outputable [a] instance Outputable Row instance Outputable Bool instance Outputable ForestLine instance Outputable LineOpt instance Outputable Source instance IsToken a => Outputable (Line a) instance Outputable a => Outputable (NonEmpty a) instance Outputable DeletedSpan instance Outputable Alignment instance IsToken a => Outputable (Up a) instance Outputable Annot instance Outputable EndOffset instance Outputable Transformation instance IsToken a => Outputable (Prim a) instance IsToken a => Outputable (DUALTreeNE Transformation (Up a) Annot (Prim a)) instance IsToken a => Outputable (DUALTreeU Transformation (Up a) Annot (Prim a)) instance IsToken a => Outputable (SourceTree a) module Language.Haskell.TokenUtils.GHC.Layout nullSrcSpan :: SrcSpan -- | Compose a new token using the given arguments. mkToken :: Token -> SimpPos -> String -> GhcPosToken gs2f :: SrcSpan -> ForestSpan f2gs :: ForestSpan -> SrcSpan gs2ss :: SrcSpan -> SimpSpan ss2gs :: SimpSpan -> SrcSpan -- | Replace any ForestLine flags already in a SrcSpan with the given ones -- TODO ++AZ++ : should not be required, convert to SimSpan then use that insertForestLineInSrcSpan :: ForestLine -> SrcSpan -> SrcSpan showSrcSpan :: SrcSpan -> String showSrcSpanF :: SrcSpan -> String -- | Create a new name token. If useQual then use the qualified -- name, if it exists. The end position is not changed, so the eventual -- realignment can know what the difference in length in the token is newNameTok :: Bool -> SrcSpan -> Name -> GhcPosToken type GhcPosToken = (Located Token, String) instance Monoid Layout instance Show (GenLocated SrcSpan Token) instance HasLoc (Located Token, String) instance HasLoc SrcSpan instance HasLoc (Located a) instance IsToken (Located Token, String) instance Allocatable ParsedSource GhcPosToken instance Outputable EndOffset instance Outputable Token instance Outputable Layout instance Outputable ForestLine instance Outputable (Entry GhcPosToken) instance Outputable (LayoutTree GhcPosToken) instance Outputable LineOpt instance Outputable Source instance Outputable (Line GhcPosToken) module Language.Haskell.TokenUtils.API class Allocatable b a allocTokens :: (Allocatable b a, IsToken a) => b -> [a] -> LayoutTree a renderLayoutTree :: IsToken a => LayoutTree a -> String -- | The IsToken class captures the different token type in use. For GHC it -- represents the type returned by getRichTokenStream, namely -- [(GHC.Located GHC.Token, String)] For haskell-src-exts this is the -- reult of lexTokenStream, namely `[HSE.Loc HSE.Token]` class (Show a, HasLoc a) => IsToken a tokenLen :: IsToken a => a -> Int isComment :: IsToken a => a -> Bool isEmpty :: IsToken a => a -> Bool mkZeroToken :: IsToken a => a isDo :: IsToken a => a -> Bool isElse :: IsToken a => a -> Bool isIn :: IsToken a => a -> Bool isLet :: IsToken a => a -> Bool isOf :: IsToken a => a -> Bool isThen :: IsToken a => a -> Bool isWhere :: IsToken a => a -> Bool tokenToString :: IsToken a => a -> String showTokenStream :: IsToken a => [a] -> String lexStringToTokens :: IsToken a => SimpSpan -> String -> [a] markToken :: IsToken a => a -> a isMarked :: IsToken a => a -> Bool class HasLoc a where getSpan a = (getLoc a, getLocEnd a) getLoc :: HasLoc a => a -> SimpPos getLocEnd :: HasLoc a => a -> SimpPos getSpan :: HasLoc a => a -> SimpSpan putSpan :: HasLoc a => a -> SimpSpan -> a