-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | the Haskell Refactorer. -- -- A Haskell 2010 refactoring tool. HaRe supports the full Haskell 2010 -- standard, through making use of the GHC API. -- -- It is tested against GHC 7.4.x and 7.6.x -- -- It currently only has emacs integration built in, community input -- welcome for others. -- -- Warning: This is alpha code. Always commit code to your version -- control system before refactoring. The developers make no warranties, -- use at your own risk. May frighten children and dogs. -- -- Current known defects: -- --
-- zmapQ f z = reverse $ downQ [] g z where -- g z' = query f z' : leftQ [] g z' ---- -- becomes -- --
-- zmapQ f z = reverse $ downQ [] (g f g)z -- -- g f z'g= query f z' : leftQ [] (g f g)g f g)z' --@package HaRe @version 0.7.0.0 -- | This module contains utilities that operate on the GHC RenamedSource module Language.Haskell.Refact.Utils.RenamedSourceUtils getFreeVariables :: (Data t, Typeable t) => t -> [NameSet] module Language.Haskell.Refact.Utils.GhcModuleGraph getModulesAsGraph :: Bool -> [ModSummary] -> Maybe ModuleName -> Graph SummaryNode summaryNodeSummary :: SummaryNode -> ModSummary -- | This is a legacy module from the pre-GHC HaRe, and will disappear -- eventually. module Language.Haskell.Refact.Utils.TypeSyn type HsExpP = HsExpr RdrName type HsPatP = Pat RdrName type HsDeclP = LHsDecl RdrName type HsDeclsP = HsGroup Name type InScopes = [Name] type SimpPos = (Int, Int) type PosToken = (Located Token, String) data Pos Pos :: !Int -> !Int -> !Int -> Pos char :: Pos -> !Int line :: Pos -> !Int column :: Pos -> !Int type Export = LIE RdrName -- | HsName is a name as it is found in the source This seems to be quite a -- close correlation type HsName = RdrName -- | The PN is the name as it occurs to the parser, and corresponds with -- the GHC.RdrName type PN = GHC.RdrName newtype PName PN :: HsName -> PName type HsModuleP = Located (HsModule RdrName) ghead :: String -> [a] -> a glast :: String -> [a] -> a gtail :: String -> [a] -> [a] gfromJust :: [Char] -> Maybe a -> a instance Show Pos instance Eq PName instance Outputable NameSpace instance Show NameSpace -- | This module contains types shared between TokenUtils and Monad, and -- exists to break import cycles module Language.Haskell.Refact.Utils.TokenUtilsTypes -- | An entry in the data structure for a particular srcspan. data Entry -- | The tokens for the SrcSpan if subtree is empty Entry :: !ForestSpan -> ![PosToken] -> Entry -- | The gap between this span end and the start of the next in the fringe -- of the tree. Deleted :: !ForestSpan -> SimpPos -> Entry 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 ForestPos = (ForestLine, Int) -- | Match a SrcSpan, using a ForestLine as the marker type ForestSpan = (ForestPos, ForestPos) data TreeId TId :: !Int -> TreeId data TokenCache TK :: !(Map TreeId (Tree Entry)) -> !TreeId -> TokenCache tkCache :: TokenCache -> !(Map TreeId (Tree Entry)) tkLastTreeId :: TokenCache -> !TreeId -- | Identifies the tree carrying the main tokens, not any work in progress -- or deleted ones mainTid :: TreeId instance Eq TreeId instance Ord TreeId instance Show TreeId instance Show ForestLine instance Eq ForestLine -- | This module contains all the code that depends on a specific version -- of GHC, and should be the only one requiring CPP module Language.Haskell.Refact.Utils.GhcVersionSpecific -- | Show a GHC API structure showGhc :: Outputable a => a -> String prettyprint :: Outputable a => a -> String lexStringToRichTokens :: RealSrcLoc -> String -> IO [PosToken] getDataConstructors :: LHsDecl n -> [LConDecl n] setGhcContext :: GhcMonad m => ModSummary -> m () module Language.Haskell.Refact.Utils.Monad -- | Result of parsing a Haskell source file. It is simply the -- TypeCheckedModule produced by GHC. type ParseResult = TypecheckedModule data VerboseLevel Debug :: VerboseLevel Normal :: VerboseLevel Off :: VerboseLevel data RefactSettings RefSet :: ![String] -> ![FilePath] -> Bool -> Maybe FilePath -> Maybe FilePath -> !Bool -> !VerboseLevel -> RefactSettings rsetGhcOpts :: RefactSettings -> ![String] rsetImportPaths :: RefactSettings -> ![FilePath] rsetExpandSplice :: RefactSettings -> Bool rsetMainFile :: RefactSettings -> Maybe FilePath -- | The sandbox directory. rsetSandbox :: RefactSettings -> Maybe FilePath rsetCheckTokenUtilsInvariant :: RefactSettings -> !Bool rsetVerboseLevel :: RefactSettings -> !VerboseLevel -- | State for refactoring a single file. Holds/hides the token stream, -- which gets updated transparently at key points. data RefactState RefSt :: !RefactSettings -> !Int -> !RefactFlags -> !StateStorage -> !(Maybe RefactModule) -> RefactState -- | Session level settings rsSettings :: RefactState -> !RefactSettings -- | Current Unique creator value, incremented every time it is used rsUniqState :: RefactState -> !Int -- | Flags for controlling generic traversals rsFlags :: RefactState -> !RefactFlags -- | Temporary storage of values while refactoring takes place rsStorage :: RefactState -> !StateStorage -- | The current module being refactored rsModule :: RefactState -> !(Maybe RefactModule) data RefactModule RefMod :: !TypecheckedModule -> ![PosToken] -> !TokenCache -> !Bool -> RefactModule rsTypecheckedMod :: RefactModule -> !TypecheckedModule -- | Original Token stream for the current module rsOrigTokenStream :: RefactModule -> ![PosToken] -- | Token stream for the current module, maybe modified, in SrcSpan tree -- form rsTokenCache :: RefactModule -> !TokenCache -- | current module has updated the token stream rsStreamModified :: RefactModule -> !Bool data RefactStashId Stash :: !String -> RefactStashId data RefactFlags RefFlags :: !Bool -> RefactFlags -- | Current traversal has already made a change rsDone :: RefactFlags -> !Bool -- | Provide some temporary storage while the refactoring is taking place data StateStorage StorageNone :: StateStorage StorageBind :: (LHsBind Name) -> StateStorage StorageSig :: (LSig Name) -> StateStorage type RefactGhc a = GhcT (StateT RefactState IO) a runRefactGhc :: RefactGhc a -> RefactState -> IO (a, RefactState) getRefacSettings :: RefactGhc RefactSettings defaultSettings :: RefactSettings logSettings :: RefactSettings -- | Initialise the GHC session, when starting a refactoring. This should -- never be called directly. initGhcSession :: Cradle -> [FilePath] -> RefactGhc () instance Eq VerboseLevel instance Show VerboseLevel instance Show RefactSettings instance Show RefactStashId instance Eq RefactStashId instance Ord RefactStashId instance (MonadPlus m, Functor m, MonadIO m, ExceptionMonad m) => MonadPlus (GhcT m) instance MonadTrans GhcT instance MonadState RefactState (GhcT (StateT RefactState IO)) instance ExceptionMonad m => ExceptionMonad (StateT s m) instance MonadIO (StateT RefactState IO) instance MonadIO (GhcT (StateT RefactState IO)) instance Show StateStorage -- | This module contains routines used to perform generic traversals of -- the GHC AST, avoiding the traps resulting from certain fields being -- populated with values defined to trigger an error if ever evaluated. -- -- This is a useful feature for tracking down bugs in GHC, but makes use -- of the GHC library problematic. module Language.Haskell.Refact.Utils.GhcUtils everythingButStaged :: Stage -> (r -> r -> r) -> r -> GenericQ (r, Bool) -> GenericQ r -- | Look up a subterm by means of a maybe-typed filter somethingStaged :: Stage -> (Maybe u) -> GenericQ (Maybe u) -> GenericQ (Maybe u) -- | Apply a monadic transformation at least somewhere somewhereMStaged :: MonadPlus m => Stage -> GenericM m -> GenericM m -- | Apply a monadic transformation at least somewhere, in bottom up order somewhereMStagedBu :: MonadPlus m => Stage -> GenericM m -> GenericM m -- | Monadic variation on everywhere everywhereMStaged :: Monad m => Stage -> GenericM m -> GenericM m -- | Monadic variation on everywhere' everywhereMStaged' :: Monad m => Stage -> GenericM m -> GenericM m -- | Bottom-up transformation everywhereStaged :: Stage -> (forall a. Data a => a -> a) -> forall a. Data a => a -> a -- | Top-down version of everywhereStaged everywhereStaged' :: Stage -> (forall a. Data a => a -> a) -> forall a. Data a => a -> a -- | Staged variation of SYB.listify The stage must be provided to avoid -- trying to modify elements which may not be present at all stages of -- AST processing. listifyStaged :: (Data a, Typeable a1) => Stage -> (a1 -> Bool) -> a -> [a1] checkItemRenamer :: Typeable a => a -> Bool -- | Full type-unifying traversal in top-down order. full_tdTUGhc :: (MonadPlus m, Monoid a) => TU a m -> TU a m -- | Top-down type-unifying traversal that is cut of below nodes where the -- argument strategy succeeds. stop_tdTUGhc :: (MonadPlus m, Monoid a) => TU a m -> TU a m allTUGhc' :: (MonadPlus m, Monoid a) => TU a m -> TU a m -- | Top-down type-preserving traversal that performs its argument strategy -- at most once. once_tdTPGhc :: MonadPlus m => TP m -> TP m -- | Bottom-up type-preserving traversal that performs its argument -- strategy at most once. once_buTPGhc :: MonadPlus m => TP m -> TP m oneTPGhc :: MonadPlus m => TP m -> TP m allTUGhc :: MonadPlus m => (a -> a -> a) -> a -> TU a m -> TU a m checkItemStage' :: MonadPlus m => Stage -> TU () m checkItemRenamer' :: MonadPlus m => TU () m -- | Apply a generic transformation everywhere in a bottom-up manner. zeverywhereStaged :: Typeable a => Stage -> GenericT -> Zipper a -> Zipper a -- | Open a zipper to the point where the Geneneric query passes. returns -- the original zipper if the query does not pass (check this) zopenStaged :: Typeable a => Stage -> GenericQ Bool -> Zipper a -> [Zipper a] -- | Apply a generic monadic transformation once at the topmost leftmost -- successful location, avoiding holes in the GHC structures zsomewhereStaged :: MonadPlus m => Stage -> GenericM m -> Zipper a -> m (Zipper a) -- | Transform a zipper opened with a given generic query transZ :: Stage -> GenericQ Bool -> (Stage -> Zipper a -> Zipper a) -> Zipper a -> Zipper a -- | Monadic transform of a zipper opened with a given generic query transZM :: Monad m => Stage -> GenericQ Bool -> (Stage -> Zipper a -> m (Zipper a)) -> Zipper a -> m (Zipper a) -- | Open a zipper to the point where the Generic query passes, returning -- the zipper and a value from the specific part of the GenericQ that -- matched. This allows the components of the query to return a specific -- transformation routine, to apply to the returned zipper zopenStaged' :: Typeable a => Stage -> GenericQ (Maybe b) -> Zipper a -> [(Zipper a, b)] -- | Open a zipper to the point where the Generic query passes, and apply -- the transformation returned from the specific part of the GenericQ -- that matched. ztransformStagedM :: (Typeable a, Monad m) => Stage -> GenericQ (Maybe (Stage -> Zipper a -> m (Zipper a))) -> Zipper a -> m (Zipper a) checkZipperStaged :: Stage -> Zipper a -> Bool -- | Climb the tree until a predicate holds upUntil :: GenericQ Bool -> Zipper a -> Maybe (Zipper a) -- | Up the zipper until a predicate holds, and then return the zipper hole findAbove :: Data a => (a -> Bool) -> Zipper a -> Maybe a module Language.Haskell.Refact.Utils.LocUtils type SimpPos = (Int, Int) unmodified :: Bool modified :: Bool simpPos0 :: (Int, Int) nullSrcSpan :: SrcSpan showToks :: [PosToken] -> String whiteSpaceTokens :: (Int, Int) -> Int -> [PosToken] realSrcLocFromTok :: PosToken -> RealSrcLoc isWhite :: PosToken -> Bool notWhite :: PosToken -> Bool isComment :: PosToken -> Bool isMultiLineComment :: PosToken -> Bool isOpenSquareBracket :: PosToken -> Bool isCloseSquareBracket :: PosToken -> Bool isIn :: PosToken -> Bool isComma :: PosToken -> Bool isBar :: PosToken -> Bool -- | Returns True if the token ends with '\n' ++AZ++: is this meaningful? endsWithNewLn :: PosToken -> Bool -- | Returns True if the token starts with `\n`. ++AZ++: is this -- meaningful? startsWithNewLn :: PosToken -> Bool hasNewLn :: PosToken -> Bool -- | Remove the extra preceding empty lines. compressPreNewLns :: [PosToken] -> [PosToken] -- | Remove the following extra empty lines. compressEndNewLns :: [PosToken] -> [PosToken] -- | Given a token stream covering multi-lines, calculate the length of the -- last line AZ: should be the last token start col, plus length of -- token. lengthOfLastLine :: [PosToken] -> Int -- | get a token stream specified by the start and end position. getToks :: (SimpPos, SimpPos) -> [PosToken] -> [PosToken] -- | 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 :: [PosToken] -> SimpPos -> PosToken -> [PosToken] -- | Delete a sequence of tokens specified by the start position and end -- position from the token stream, then adjust the remaining token stream -- to preserve layout deleteToks :: [PosToken] -> SimpPos -> SimpPos -> [PosToken] -- | remove at most n white space tokens from the beginning of ts doRmWhites :: Int -> [PosToken] -> [PosToken] -- | get all the source locations (use locations) in an AST phrase t -- according the the occurrence order of identifiers. srcLocs :: Data t => t -> [SimpPos] -- | Get the first SrcSpan found, in top down traversal getSrcSpan :: Data t => t -> Maybe SrcSpan -- | Get all the source locations in a given syntax fragment getAllSrcLocs :: Data t => t -> [(SimpPos, SimpPos)] getBiggestStartEndLoc :: Data t => t -> (SimpPos, SimpPos) -- | Extend the given position forwards to the end of the file while the -- supplied condition holds extendForwards :: [PosToken] -> (SimpPos, SimpPos) -> (PosToken -> Bool) -> (SimpPos, SimpPos) -- | Extend the given position backwards to the front of the file while the -- supplied condition holds extendBackwards :: [PosToken] -> (SimpPos, SimpPos) -> (PosToken -> Bool) -> (SimpPos, SimpPos) -- | Get the start&end location of syntax phrase t, then extend the end -- location to cover the comment/white spaces or new line which starts in -- the same line as the end location TODO: deprecate this in favour of -- startEndLocIncComments startEndLocIncFowComment :: Data t => [PosToken] -> t -> (SimpPos, SimpPos) -- | 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 :: RealSrcLoc -> Int -> Bool -> String -> IO [PosToken] -- | 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 :: String -> IO [PosToken] lexStringToRichTokens :: RealSrcLoc -> String -> IO [PosToken] prettyprint :: Outputable a => a -> String prettyprintPatList :: (t -> String) -> Bool -> [t] -> String addLocInfo :: (LHsBind Name, [PosToken]) -> RefactGhc (LHsBind Name, [PosToken]) -- | Get the start of the line before the pos, getLineOffset :: [PosToken] -> SimpPos -> Int tokenCol :: PosToken -> Int tokenColEnd :: PosToken -> Int tokenRow :: PosToken -> Int tokenPos :: (GenLocated SrcSpan t1, t) -> SimpPos tokenPosEnd :: (GenLocated SrcSpan t1, t) -> SimpPos tokenCon :: PosToken -> String increaseSrcSpan :: SimpPos -> PosToken -> PosToken getGhcLoc :: SrcSpan -> (Int, Int) getGhcLocEnd :: SrcSpan -> (Int, Int) getLocatedStart :: GenLocated SrcSpan t -> (Int, Int) getLocatedEnd :: GenLocated SrcSpan t -> (Int, Int) getStartEndLoc :: Data t => t -> (SimpPos, SimpPos) startEndLocGhc :: Located b -> (SimpPos, SimpPos) realSrcLocEndTok :: PosToken -> RealSrcLoc fileNameFromTok :: PosToken -> FastString -- | 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 :: (SimpPos, SimpPos) -> [PosToken] -> ([PosToken], [PosToken], [PosToken]) -- | Get around lack of instance Eq when simply testing for empty list emptyList :: [t] -> Bool nonEmptyList :: [t] -> Bool -- | 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 :: Data t => [PosToken] -> t -> (SimpPos, SimpPos) startEndLocIncComments' :: [PosToken] -> (SimpPos, SimpPos) -> (SimpPos, SimpPos) -- | Split a set of comment tokens into the ones that belong with the -- startLine and those that belong with the endLine divideComments :: Int -> Int -> [PosToken] -> ([PosToken], [PosToken]) isWhiteSpace :: PosToken -> Bool notWhiteSpace :: PosToken -> Bool isDoubleColon :: PosToken -> Bool isEmpty :: PosToken -> Bool isWhereOrLet :: PosToken -> Bool isWhere :: PosToken -> Bool isLet :: PosToken -> Bool -- | Get the indent of the line before, taking into account in-line -- 'where', 'let', 'in' and 'do' tokens getIndentOffset :: [PosToken] -> SimpPos -> Int splitOnNewLn :: [PosToken] -> ([PosToken], [PosToken]) tokenLen :: PosToken -> Int newLnToken :: PosToken -> PosToken newLinesToken :: Int -> PosToken -> PosToken groupTokensByLine :: [PosToken] -> [[PosToken]] -- | sort out line numbering so that they are always monotonically -- increasing. monotonicLineToks :: [PosToken] -> [PosToken] -- | Adjust token stream to cater for changes in token length due to token -- renaming reSequenceToks :: [PosToken] -> [PosToken] -- | Compose a new token using the given arguments. mkToken :: Token -> SimpPos -> String -> PosToken mkZeroToken :: PosToken -- | Mark a token so that it can be use to trigger layout checking later -- when the toks are retrieved markToken :: PosToken -> PosToken -- | Does a token have the file mark in it isMarked :: PosToken -> Bool -- | Add a constant line and column offset to a span of tokens addOffsetToToks :: SimpPos -> [PosToken] -> [PosToken] -- | Transfer the location information from the first param to the second matchTokenPos :: PosToken -> PosToken -> PosToken instance Show (GenLocated SrcSpan Token) -- | This module contains an API to manage a token stream. -- -- This API is used internally by MonadFunctions and the other utility -- modules, it should probably never be used directly in a refactoring. module Language.Haskell.Refact.Utils.TokenUtils -- | Keep track of when tokens are reversed, to avoid confusion data ReversedToks RT :: [PosToken] -> ReversedToks reverseToks :: [PosToken] -> ReversedToks unReverseToks :: ReversedToks -> [PosToken] reversedToks :: ReversedToks -> [PosToken] -- | An entry in the data structure for a particular srcspan. data Entry -- | The tokens for the SrcSpan if subtree is empty Entry :: !ForestSpan -> ![PosToken] -> Entry -- | The gap between this span end and the start of the next in the fringe -- of the tree. Deleted :: !ForestSpan -> SimpPos -> Entry -- | 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 initTokenCache :: [PosToken] -> TokenCache -- | 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. TODO: consider returning an Either. Although in -- reality the error should never happen getTokensFor :: Bool -> Tree Entry -> SrcSpan -> (Tree Entry, [PosToken]) -- | Get the tokens preceding a given SrcSpan getTokensBefore :: Tree Entry -> SrcSpan -> (Tree Entry, ReversedToks) -- | 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 :: Tree Entry -> SrcSpan -> PosToken -> Tree Entry -- | 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 :: Tree Entry -> SrcSpan -> [PosToken] -> (Tree Entry, SrcSpan, Tree Entry) -- | 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 -> ForestSpan -- | Get the start and end position of a SrcSpan spanStartEnd :: -- GHC.SrcSpan -> (SimpPos,SimpPos) spanStartEnd sspan = (getGhcLoc -- sspan,getGhcLocEnd sspan) spanStartEnd :: SrcSpan -> ForestSpan -- | 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 :: Tree Entry -> ForestSpan -> Tree Entry -- | Removes a ForestSpan and its tokens from the forest. removeSrcSpan :: Tree Entry -> ForestSpan -> (Tree Entry, Tree Entry) -- | Retrieve a path to the tree containing a ForestSpan from the forest, -- inserting it if not already present getSrcSpanFor :: Tree Entry -> ForestSpan -> (Tree Entry, Tree Entry) -- | Retrieve all the tokens at the leaves of the tree, in order. Marked -- tokens are re-aligned, and gaps are closed. retrieveTokensFinal :: Tree Entry -> [PosToken] -- | 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 :: Tree Entry -> [PosToken] retrieveTokens' :: Tree Entry -> [Entry] -- | 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 :: Tree Entry -> SrcSpan -> SrcSpan -> Positioning -> [PosToken] -> (Tree Entry, SrcSpan) -- | Add new tokens after the given SrcSpan, constructing a new SrcSpan in -- the process addToksAfterSrcSpan :: Tree Entry -> SrcSpan -> Positioning -> [PosToken] -> (Tree Entry, SrcSpan) -- | Add new tokens belonging to an AST fragment after a given SrcSpan, and -- re-sync the AST fragment to match the new location addDeclToksAfterSrcSpan :: Data t => Tree Entry -> SrcSpan -> Positioning -> [PosToken] -> Located t -> (Tree Entry, SrcSpan, Located t) treeIdFromForestSpan :: ForestSpan -> TreeId replaceTokenInCache :: TokenCache -> SrcSpan -> PosToken -> TokenCache putToksInCache :: TokenCache -> SrcSpan -> [PosToken] -> (TokenCache, SrcSpan) removeToksFromCache :: TokenCache -> SrcSpan -> TokenCache getTreeFromCache :: SrcSpan -> TokenCache -> Tree Entry replaceTreeInCache :: SrcSpan -> Tree Entry -> TokenCache -> TokenCache -- | Assuming most recent operation has stashed the old tokens, sync the -- given AST to the most recent stash entry syncAstToLatestCache :: Data t => TokenCache -> Located t -> Located t reAlignMarked :: [PosToken] -> [PosToken] -- | Convert a simple (start,end) position to a SrcSpan belonging to the -- file in the tree posToSrcSpan :: Tree Entry -> (SimpPos, SimpPos) -> SrcSpan -- | Convert a simple (start,end) position to a SrcSpan belonging to the -- file in the given token posToSrcSpanTok :: PosToken -> (SimpPos, SimpPos) -> SrcSpan fileNameFromTok :: PosToken -> FastString -- | Synchronise a located AST fragment to use a newly created SrcSpan in -- the token tree. syncAST :: Data t => Located t -> SrcSpan -> Tree Entry -> (Located t, Tree Entry) placeToksForSpan :: Tree Entry -> SrcSpan -> Tree Entry -> Positioning -> [PosToken] -> [PosToken] limitPrevToks :: ReversedToks -> SrcSpan -> ReversedToks reIndentToks :: Positioning -> [PosToken] -> [PosToken] -> [PosToken] -- | 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 :: [PosToken] -> [PosToken] reAlignToks :: [PosToken] -> [PosToken] -- | Split a forest of trees into a (begin,middle,end) according to a -- ForestSpan, such that no tokens are included in begin or end belonging -- to the ForestSpan, and all of middle has some part of the ForestSpan splitForestOnSpan :: Forest Entry -> ForestSpan -> ([Tree Entry], [Tree Entry], [Tree Entry]) -- | 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 -- | 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 doSplitTree :: Tree Entry -> ForestSpan -> ([Tree Entry], [Tree Entry], [Tree Entry]) -- | 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 :: Tree Entry -> ForestSpan -> ([Tree Entry], [Tree Entry], [Tree Entry]) splitSubToks :: Tree Entry -> (ForestPos, ForestPos) -> ([Tree Entry], [Tree Entry], [Tree Entry]) -- | Extract the start and end position of a span, without any leading or -- trailing comments nonCommentSpan :: [PosToken] -> (SimpPos, SimpPos) -- | Utility function to either return True or throw an error to report the -- problem invariantOk :: Tree Entry -> Bool -- | 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 nullSpan 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 :: Tree Entry -> [String] -- | Make a tree representing a particular set of tokens mkTreeFromTokens :: [PosToken] -> Tree Entry -- | Make a tree representing a particular set of tokens mkTreeFromSpanTokens :: ForestSpan -> [PosToken] -> Tree Entry showForest :: [Tree Entry] -> [String] showTree :: Tree Entry -> String showSrcSpan :: SrcSpan -> String showSrcSpanF :: SrcSpan -> String ghcSpanStartEnd :: SrcSpan -> ((Int, Int), (Int, Int)) -- | Insert a new node after the designated one in the tree insertNodeAfter :: Tree Entry -> Tree Entry -> Tree Entry -> Tree Entry -- | 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 :: TreePos Full Entry -> ReversedToks -- | Open a zipper so that its focus is the given node NOTE: the node must -- already be in the tree openZipperToNode :: Tree Entry -> TreePos Full Entry -> TreePos Full Entry -- | 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 :: ForestSpan -> TreePos Full Entry -> TreePos Full Entry -- | Strip out the version markers forestSpanToSimpPos :: ForestSpan -> (SimpPos, SimpPos) -- | Strip out the version markers forestSpanToGhcPos :: ForestSpan -> (SimpPos, SimpPos) -- | Extract an encoded ForestLine from a GHC line ghcLineToForestLine :: Int -> ForestLine forestLineToGhcLine :: ForestLine -> Int forestSpanToSrcSpan :: ForestSpan -> SrcSpan -- | Checks if the version is non-zero forestPosVersionSet :: ForestPos -> Bool -- | Checks if the version is zero forestPosVersionNotSet :: ForestPos -> Bool forestSpanLenChanged :: ForestSpan -> Bool -- | Gets the version numbers forestSpanVersions :: ForestSpan -> (Int, Int) -- | Checks if the version is non-zero in either position forestSpanVersionSet :: ForestSpan -> Bool -- | Checks if the version is zero in both positions forestSpanVersionNotSet :: ForestSpan -> Bool insertForestLineInSrcSpan :: ForestLine -> SrcSpan -> SrcSpan insertLenChangedInSrcSpan :: Bool -> Bool -> SrcSpan -> SrcSpan insertVersionsInSrcSpan :: Int -> Int -> SrcSpan -> SrcSpan srcSpanToForestSpan :: SrcSpan -> ForestSpan nullSpan :: ForestSpan nullPos :: ForestPos simpPosToForestSpan :: (SimpPos, SimpPos) -> ForestSpan srcPosToSimpPos :: (Int, Int) -> (Int, Int) showForestSpan :: ForestSpan -> String -- | Process the leaf nodes of a tree to remove all deleted spans deleteGapsToks :: [Entry] -> [PosToken] -- | Process the leaf nodes of a tree to remove all deleted spans deleteGapsToks' :: [Entry] -> [(SimpPos, String, ForestSpan, [PosToken])] -- | 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 :: Tree Entry -> ForestSpan -> SimpPos stripForestLines :: [PosToken] -> [PosToken] -- | Neat 2-dimensional drawing of a tree. drawTreeEntry :: Tree Entry -> String -- | Call drawTreeEntry on the entire token cache drawTokenCache :: TokenCache -> String -- | Call drawTreeEntry on the entire token cache drawTokenCacheDetailed :: TokenCache -> String -- | Neat 2-dimensional drawing of a forest. drawForestEntry :: Forest Entry -> String drawEntry :: Tree Entry -> [String] instance Show Entry => Show Entry instance Show ReversedToks instance Show Positioning instance Ord ForestLine module Language.Haskell.Refact.Utils.MonadFunctions -- | fetch the final tokens fetchToksFinal :: RefactGhc [PosToken] -- | fetch the pristine token stream fetchOrigToks :: RefactGhc [PosToken] -- | fetch the possibly modified tokens. Deprecated fetchToks :: RefactGhc [PosToken] getTypecheckedModule :: RefactGhc TypecheckedModule getRefactStreamModified :: RefactGhc Bool getRefactInscopes :: RefactGhc InScopes getRefactRenamed :: RefactGhc RenamedSource putRefactRenamed :: RenamedSource -> RefactGhc () getRefactParsed :: RefactGhc ParsedSource putParsedModule :: TypecheckedModule -> [PosToken] -> RefactGhc () clearParsedModule :: RefactGhc () getRefactFileName :: RefactGhc (Maybe FilePath) -- | Replace a token occurring in a given GHC.SrcSpan replaceToken :: SrcSpan -> PosToken -> RefactGhc () -- | Replace the tokens for a given GHC.SrcSpan, return new GHC.SrcSpan -- delimiting new tokens putToksForSpan :: SrcSpan -> [PosToken] -> RefactGhc SrcSpan -- | Get the current tokens for a given GHC.SrcSpan. getToksForSpan :: SrcSpan -> RefactGhc [PosToken] -- | Get the current tokens preceding a given GHC.SrcSpan. getToksBeforeSpan :: SrcSpan -> RefactGhc ReversedToks -- | Replace the tokens for a given GHC.SrcSpan, return GHC.SrcSpan they -- are placed in putToksForPos :: (SimpPos, SimpPos) -> [PosToken] -> RefactGhc SrcSpan -- | Add tokens after a designated GHC.SrcSpan putToksAfterSpan :: SrcSpan -> Positioning -> [PosToken] -> RefactGhc SrcSpan -- | Add tokens after a designated position putToksAfterPos :: (SimpPos, SimpPos) -> Positioning -> [PosToken] -> RefactGhc SrcSpan -- | Add tokens after a designated GHC.SrcSpan, and update the AST fragment -- to reflect it putDeclToksAfterSpan :: Data t => SrcSpan -> Located t -> Positioning -> [PosToken] -> RefactGhc (Located t) -- | Remove a GHC.SrcSpan and its associated tokens removeToksForSpan :: SrcSpan -> RefactGhc () -- | Remove a GHC.SrcSpan and its associated tokens removeToksForPos :: (SimpPos, SimpPos) -> RefactGhc () syncDeclToLatestStash :: Data t => (Located t) -> RefactGhc (Located t) -- | Print the Token Tree for debug purposes drawTokenTree :: String -> RefactGhc () -- | Print detailed Token Tree for debug purposes drawTokenTreeDetailed :: String -> RefactGhc () -- | Get the Token Tree for debug purposes getTokenTree :: RefactGhc (Tree Entry) getRefactDone :: RefactGhc Bool setRefactDone :: RefactGhc () clearRefactDone :: RefactGhc () setStateStorage :: StateStorage -> RefactGhc () getStateStorage :: RefactGhc StateStorage logm :: String -> RefactGhc () updateToks :: Data t => Located t -> Located t -> (Located t -> [Char]) -> Bool -> RefactGhc () updateToksWithPos :: Data t => (SimpPos, SimpPos) -> t -> (t -> [Char]) -> Bool -> RefactGhc () initRefactModule :: TypecheckedModule -> [PosToken] -> Maybe RefactModule -- | This module contains a collection of program analysis and -- transformation functions (the API) that work over the Type Decorated -- AST. Most of the functions defined in the module are taken directly -- from the API, but in some cases are modified to work with the type -- decorated AST. -- -- In particular some new functions have been added to make type -- decorated AST traversals easier. -- -- In HaRe, in order to preserve the comments and layout of refactored -- programs, a refactoring modifies not only the AST but also the token -- stream, and the program source after the refactoring is extracted from -- the token stream rather than the AST, for the comments and layout -- information is kept in the token steam instead of the AST. As a -- consequence, a program transformation function from this API modifies -- both the AST and the token stream (unless explicitly stated). So when -- you build your own program transformations, try to use the API to do -- the transformation, as this can liberate you from caring about the -- token stream. -- -- This type decorated API is still in development. Any suggestions and -- comments are very much welcome. module Language.Haskell.Refact.Utils.TypeUtils -- | Process the inscope relation returned from the parsing and module -- analysis pass, and return a list of four-element tuples. Each tuple -- contains an identifier name, the identifier's namespace info, the -- identifier's defining module name and its qualifier name. -- -- The same identifier may have multiple entries in the result because it -- may have different qualifiers. This makes it easier to decide whether -- the identifier can be used unqualifiedly by just checking whether -- there is an entry for it with the qualifier field being Nothing. inScopeInfo :: InScopes -> [(String, NameSpace, ModuleName, Maybe ModuleName)] -- | Return True if the identifier is inscope and can be used without a -- qualifier. isInScopeAndUnqualified :: String -> InScopes -> Bool -- | Return True if the identifier is inscope and can be used without a -- qualifier. The identifier name string may have a qualifier already -- NOTE: may require qualification based on name clash with an existing -- identifier. isInScopeAndUnqualifiedGhc :: String -> (Maybe Name) -> RefactGhc Bool inScopeNames :: String -> RefactGhc [Name] -- | Return True if an identifier is exported by the module currently being -- refactored. isExported :: Name -> RefactGhc Bool -- | Return True if an identifier is explicitly exported by the module. isExplicitlyExported :: Name -> RenamedSource -> Bool -- | Return True if the current module is exported either by default or by -- specifying the module name in the export. modIsExported :: ModuleName -> RenamedSource -> Bool -- | True if the name is a field name isFieldName :: Name -> Bool -- | True if the name is a field name isClassName :: Name -> Bool -- | True if the name is a class instance isInstanceName :: Name -> Bool -- | Collect the identifiers (in PName format) in a given syntax phrase. hsPNs :: Data t => t -> [PName] hsBinds :: HsValBinds t => t -> [LHsBind Name] replaceBinds :: HsValBinds t => t -> [LHsBind Name] -> t class Data t => HsValBinds t hsValBinds :: HsValBinds t => t -> HsValBinds Name replaceValBinds :: HsValBinds t => t -> HsValBinds Name -> t isDeclaredIn :: HsValBinds t => Name -> t -> Bool -- | Collect the free and declared variables (in the GHC.Name format) in a -- given syntax phrase t. In the result, the first list contains the free -- variables, and the second list contains the declared variables. -- Expects RenamedSource hsFreeAndDeclaredPNs :: Data t => t -> ([Name], [Name]) -- | The same as hsFreeAndDeclaredPNs except that the returned -- variables are in the String format. hsFreeAndDeclaredNames :: Data t => t -> ([String], [String]) -- | Experiment with GHC fvs stuff getFvs :: [LHsBind Name] -> [([Name], NameSet)] getFreeVars :: [LHsBind Name] -> [Name] getDeclaredVars :: [LHsBind Name] -> [Name] -- | Given syntax phrases e and t, if e occurs in t, then return those -- variables which are declared in t and accessible to e, otherwise -- return []. hsVisiblePNs :: (FindEntity e, Data e, Data t) => e -> t -> [Name] -- | Same as hsVisiblePNs except that the returned identifiers are -- in String format. hsVisibleNames :: (FindEntity t1, Data t1, Data t2) => t1 -> t2 -> [String] -- | hsFDsFromInside is different from hsFreeAndDeclaredPNs -- in that: given an syntax phrase t, hsFDsFromInside returns not -- only the declared variables that are visible from outside of t, but -- also those declared variables that are visible to the main expression -- inside t. NOTE: Expects to be given RenamedSource hsFDsFromInside :: Data t => t -> ([Name], [Name]) -- | The same as hsFDsFromInside except that the returned variables -- are in the String format hsFDNamesFromInside :: Data t => t -> RefactGhc ([String], [String]) -- | Return True if a string is a lexically valid variable name. isVarId :: String -> Bool -- | Return True if a string is a lexically valid constructor name. isConId :: String -> Bool -- | Return True if a string is a lexically valid operator name. isOperator :: String -> Bool -- | Return True if a PName is a toplevel PName. isTopLevelPN :: Name -> RefactGhc Bool -- | Return True if a PName is a local PName. isLocalPN :: Name -> Bool -- | Return True if a PName is a qualified PName. AZ:NOTE: this tests the -- use instance, the underlying name may be qualified. e.g. used name is -- zip, GHC.List.zip NOTE2: not sure if this gives a meaningful result -- for a GHC.Name isQualifiedPN :: Name -> RefactGhc Bool -- | Return True if a PName is a function/pattern name defined in t. isFunOrPatName :: Data t => Name -> t -> Bool -- | Return True if a declaration is a type signature declaration. -- isTypeSig ::HsDeclP->Bool isTypeSig (TiDecorate.Dec (HsTypeSig loc -- is c tp))=True isTypeSig :: Located (Sig a) -> Bool -- | Return True if a declaration is a function definition. isFunBindP :: HsDeclP -> Bool isFunBindR :: LHsBind t -> Bool -- | Returns True if a declaration is a pattern binding. isPatBindP :: HsDeclP -> Bool isPatBindR :: LHsBind t -> Bool -- | Return True if a declaration is a pattern binding which only defines a -- variable value. isSimplePatBind :: Data t => LHsBind t -> Bool -- | Return True if a declaration is a pattern binding but not a simple -- one. isComplexPatBind :: LHsBind Name -> Bool -- | Return True if a declaration is a function/pattern definition. isFunOrPatBindP :: HsDeclP -> Bool -- | Return True if a declaration is a function/pattern definition. isFunOrPatBindR :: LHsBind t -> Bool -- | Return True if the identifier is unqualifiedly used in the given -- syntax phrase. usedWithoutQualR :: GHC.Name -> GHC.ParsedSource -- -> Bool usedWithoutQualR :: Data t => Name -> t -> Bool -- | Return True if the identifier is used in the RHS if a function/pattern -- binding. isUsedInRhs :: Data t => (Located Name) -> t -> Bool -- | Return True if the identifier occurs in the given syntax phrase. findPNT :: Data t => Located Name -> t -> Bool -- | Return True if the identifier occurs in the given syntax phrase. findPN :: Data t => Name -> t -> Bool -- | Find all occurrences with location of the given name findAllNameOccurences :: Data t => Name -> t -> [(Located Name)] -- | Return True if any of the specified PNames ocuur in the given syntax -- phrase. findPNs :: Data t => [Name] -> t -> Bool -- | Returns True is a syntax phrase, say a, is part of another syntax -- phrase, say b. findEntity :: (FindEntity a, Data b, Typeable b) => a -> b -> Bool findEntity' :: (Data a, Data b) => a -> b -> Maybe (SimpPos, SimpPos) -- | Return True if syntax phrases t1 and t2 refer to the same one. sameOccurrence :: (Located t) -> (Located t) -> Bool -- | Return True if the function/pattern binding defines the specified -- identifier. defines :: Name -> LHsBind Name -> Bool definesP :: PName -> HsDeclP -> Bool -- | Return True if the declaration defines the type signature of the -- specified identifier. definesTypeSig :: Name -> LSig Name -> Bool sameBind :: LHsBind Name -> LHsBind Name -> Bool class Data t => UsedByRhs t usedByRhs :: UsedByRhs t => t -> [Name] -> Bool isMainModule :: Module -> Bool getModule :: RefactGhc Module -- | Return the identifier's defining location. defineLoc::PNT->SrcLoc defineLoc :: Located Name -> SrcLoc -- | Return the identifier's source location. useLoc::PNT->SrcLoc useLoc :: (Located Name) -> SrcLoc -- | Given the syntax phrase, find the largest-leftmost expression -- contained in the region specified by the start and end position, if -- found. locToExp :: (Data t, Typeable n) => SimpPos -> SimpPos -> t -> Maybe (Located (HsExpr n)) -- | Find the identifier(in GHC.Name format) whose start position is -- (row,col) in the file specified by the fileName, and returns -- Nothing if such an identifier does not exist. locToName :: Data t => FastString -> SimpPos -> t -> Maybe (Located Name) -- | Find the identifier(in GHC.RdrName format) whose start position is -- (row,col) in the file specified by the fileName, and returns -- Nothing if such an identifier does not exist. locToRdrName :: Data t => FastString -> SimpPos -> t -> Maybe (Located RdrName) -- | Find the identifier with the given name. This looks through the given -- syntax phrase for the first GHC.Name which matches. Because it is -- Renamed source, the GHC.Name will include its defining location. -- Returns Nothing if the name is not found. getName :: Data t => String -> t -> Maybe Name -- | Adding a declaration to the declaration list of the given syntax -- phrase(so far only adding function/pattern binding has been tested). -- If the second argument is Nothing, then the declaration will be added -- to the beginning of the declaration list, but after the data type -- declarations is there is any. addDecl :: (Data t, HsValBinds t) => t -> Maybe Name -> (LHsBind Name, [LSig Name], Maybe [PosToken]) -> Bool -> RefactGhc t -- | Add identifiers (given by the third argument) to the explicit entity -- list in the declaration importing the specified module name. This -- function does nothing if the import declaration does not have an -- explicit entity list. addItemsToImport :: ModuleName -> RenamedSource -> [Name] -> RefactGhc RenamedSource -- | add items to the hiding list of an import declaration which imports -- the specified module. addHiding :: ModuleName -> RenamedSource -> [Name] -> RefactGhc RenamedSource addParamsToDecls :: [LHsBind Name] -> Name -> [Name] -> Bool -> RefactGhc [LHsBind Name] addActualParamsToRhs :: (Typeable t, Data t) => Bool -> Name -> [Name] -> t -> RefactGhc t -- | Add identifiers to the export list of a module. If the second argument -- is like: Just p, then do the adding only if p occurs in the export -- list, and the new identifiers are added right after p in the export -- list. Otherwise the new identifiers are add to the beginning of the -- export list. In the case that the export list is emport, then if the -- third argument is True, then create an explict export list to contain -- only the new identifiers, otherwise do nothing. addImportDecl :: RenamedSource -> ModuleName -> Maybe FastString -> Bool -> Bool -> Bool -> Maybe String -> Bool -> [Name] -> RefactGhc RenamedSource -- | Remove those specified items from the entity list in the import -- declaration. -- -- Remove the specified entities from the module's exports. The entities -- can be specified in either of two formats: i.e. either specify the -- module names and identifier names to be removed, so just given the -- exact AST for these entities. -- -- Duplicate a function/pattern binding declaration under a new name -- right after the original one. Also updates the token stream. duplicateDecl :: Data t => [LHsBind Name] -> t -> Name -> Name -> RefactGhc [LHsBind Name] -- | Remove the declaration (and the type signature is the second parameter -- is True) that defines the given identifier from the declaration list. rmDecl :: Data t => Name -> Bool -> t -> RefactGhc (t, LHsBind Name, Maybe (LSig Name)) -- | Remove the type signature that defines the given identifier's type -- from the declaration list. rmTypeSig :: Data t => Name -> t -> RefactGhc (t, Maybe (LSig Name)) -- | Remove multiple type signatures rmTypeSigs :: Data t => [Name] -> t -> RefactGhc (t, [LSig Name]) -- | Remove the qualifier from the given identifiers in the given syntax -- phrase. rmQualifier :: Data t => [Name] -> t -> RefactGhc t -- | Replace all occurences of a top level GHC.Name with a qualified -- version. qualifyToplevelName :: Name -> RefactGhc () -- | Rename each occurrences of the identifier in the given syntax phrase -- with the new name. If the Bool parameter is True, then modify both the -- AST and the token stream, otherwise only modify the AST. TODO: the -- syntax phrase is required to be GHC.Located, not sure how to specify -- this without breaking the everywhereMStaged call renamePN :: Data t => Name -> Name -> Bool -> Bool -> t -> RefactGhc t -- | Check whether the specified identifier is declared in the given syntax -- phrase t, if so, rename the identifier by creating a new name -- automatically. If the Bool parameter is True, the token stream will be -- modified, otherwise only the AST is modified. autoRenameLocalVar :: HsValBinds t => Bool -> Name -> t -> RefactGhc t -- | Show a list of entities, the parameter f is a function that specifies -- how to format an entity. showEntities :: (t -> String) -> [t] -> String -- | Show a PName in a format like: pn(at row:r, col: c). showPNwithLoc :: Located Name -> String defaultPN :: PName defaultName :: Name -- | Default expression. defaultExp :: HsExpP ghcToPN :: RdrName -> PName lghcToPN :: Located RdrName -> PName -- | If an expression consists of only one identifier then return this -- identifier in the GHC.Name format, otherwise return the default Name expToName :: Located (HsExpr Name) -> Name nameToString :: Name -> String -- | If a pattern consists of only one identifier then return this -- identifier, otherwise return Nothing patToPNT :: LPat Name -> Maybe Name -- | Compose a pattern from a pName. pNtoPat :: Name -> Pat Name -- | Find those declarations(function/pattern binding and type signature) -- which define the specified PNames. incTypeSig indicates whether the -- corresponding type signature will be included. definingDecls :: [PName] -> [HsDeclP] -> Bool -> Bool -> [HsDeclP] -- | Return the list of identifiers (in PName format) defined by a -- function/pattern binding. definedPNs :: LHsBind Name -> [Name] -- | Find those declarations(function/pattern binding) which define the -- specified GHC.Names. incTypeSig indicates whether the corresponding -- type signature will be included. definingDeclsNames :: [Name] -> [LHsBind Name] -> Bool -> Bool -> [LHsBind Name] -- | Find those declarations(function/pattern binding) which define the -- specified GHC.Names. incTypeSig indicates whether the corresponding -- type signature will be included. definingDeclsNames' :: Data t => [Name] -> t -> [LHsBind Name] -- | Find those type signatures for the specified GHC.Names. definingSigsNames :: Data t => [Name] -> t -> [LSig Name] -- | Find all Located Names in the given Syntax phrase. allNames :: Data t => t -> [Located Name] mkRdrName :: String -> RdrName -- | Make a new GHC.Name, using the Unique Int sequence stored in the -- RefactState. mkNewGhcName :: Maybe Module -> String -> RefactGhc Name -- | Create a new name base on the old name. Suppose the old name is -- f, then the new name would be like f_i where -- i is an integer. mkNewName :: String -> [String] -> Int -> String mkNewToplevelName :: Module -> String -> SrcSpan -> RefactGhc Name -- | Check if the proposed new name will conflict with an existing export causeNameClashInExports :: Name -> Name -> ModuleName -> RenamedSource -> Bool prettyprint :: Outputable a => a -> String -- | Remove at most offset whitespaces from each line in the -- tokens removeOffset :: Int -> [PosToken] -> [PosToken] getDeclAndToks :: HsValBinds t => Name -> Bool -> [PosToken] -> t -> ([LHsBind Name], [PosToken]) -- | Get the signature and tokens for a declaration getSigAndToks :: Data t => Name -> t -> [PosToken] -> Maybe (LSig Name, [PosToken]) -- | 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 -> PosToken -- | Take a list of strings and return a list with the longest prefix of -- spaces removed stripLeadingSpaces :: [String] -> [String] instance UsedByRhs (Stmt Name) instance UsedByRhs (HsExpr Name) instance UsedByRhs (LHsBind Name) instance UsedByRhs (HsBind Name) instance UsedByRhs [LHsBind Name] instance UsedByRhs (Match Name) instance UsedByRhs (HsValBinds Name) instance UsedByRhs (LHsBinds Name) instance UsedByRhs RenamedSource instance FindEntity (Located (HsDecl Name)) instance FindEntity (Located (HsBindLR Name Name)) instance FindEntity (Located (HsExpr Name)) instance FindEntity (Located Name) instance FindEntity Name instance HsValBinds (LStmt Name) instance HsValBinds [LStmt Name] instance HsValBinds (LGRHS Name) instance HsValBinds [LGRHS Name] instance HsValBinds (LHsExpr Name) instance HsValBinds [LHsBind Name] instance HsValBinds (LHsBind Name) instance HsValBinds (LHsBinds Name) instance HsValBinds (Stmt Name) instance HsValBinds (HsExpr Name) instance HsValBinds (HsBind Name) instance HsValBinds (Match Name) instance HsValBinds (LMatch Name) instance HsValBinds [LMatch Name] instance HsValBinds (MatchGroup Name) instance HsValBinds (GRHSs Name) instance HsValBinds (HsLocalBinds Name) instance HsValBinds (HsGroup Name) instance HsValBinds (HsValBinds Name) instance HsValBinds RenamedSource module Language.Haskell.Refact.Utils -- | Return True if syntax phrases t1 and t2 refer to the same one. sameOccurrence :: (Located t) -> (Located t) -> Bool -- | Load a module graph into the GHC session, starting from main loadModuleGraphGhc :: Maybe FilePath -> RefactGhc () -- | Once the module graph has been loaded, load the given module into the -- RefactGhc monad getModuleGhc :: FilePath -> RefactGhc () -- | Parse a single source file into a GHC session parseSourceFileGhc :: String -> RefactGhc () -- | In the existing GHC session, put the requested TypeCheckedModule into -- the RefactGhc monad getModuleDetails :: ModSummary -> RefactGhc () -- | Manage a whole refactor session. Initialise the monad, load the whole -- project if required, and then apply the individual refactorings, and -- write out the resulting files. -- -- It is intended that this forms the umbrella function, in which -- applyRefac is called runRefacSession :: RefactSettings -> Cradle -> RefactGhc [ApplyRefacResult] -> IO [FilePath] -- | Apply a refactoring (or part of a refactoring) to a single module applyRefac :: RefactGhc a -> RefacSource -> RefactGhc (ApplyRefacResult, a) -- | Returns True if any of the results has its modified flag set refactDone :: [ApplyRefacResult] -> Bool -- | The result of a refactoring is the file, a flag as to whether it was -- modified, the updated token stream, and the updated AST type ApplyRefacResult = ((FilePath, Bool), ([PosToken], RenamedSource)) data RefacSource RSFile :: FilePath -> RefacSource RSMod :: ModSummary -> RefacSource RSAlreadyLoaded :: RefacSource -- | Update the occurrence of one syntax phrase in a given scope by another -- syntax phrase of the same type update :: Update t t1 => t -> t -> t1 -> RefactGhc t1 -- | From file name to module name. fileNameToModName :: FilePath -> RefactGhc ModuleName fileNameFromModSummary :: ModSummary -> FilePath -- | Extract the module name from the parsed source, if there is one getModuleName :: ParsedSource -> Maybe (ModuleName, String) -- | Return the client modules and file names. The client modules of -- module, say m, are those modules which directly or indirectly import -- module m. clientModsAndFiles :: GhcMonad m => ModuleName -> m [ModSummary] -- | Return the server module and file names. The server modules of module, -- say m, are those modules which are directly or indirectly imported by -- module m. This can only be called in a live GHC session serverModsAndFiles :: GhcMonad m => ModuleName -> m [ModSummary] -- | Return True if the given module name exists in the project. -- isAnExistingMod::( ) =>ModuleName->PFE0MT n i ds ext m Bool -- -- Get the current module graph, provided we are in a live GHC session getCurrentModuleGraph :: RefactGhc ModuleGraph sortCurrentModuleGraph :: RefactGhc [SCC ModSummary] pwd :: IO FilePath instance Show ModuleName instance (Data t, OutputableBndr n1, OutputableBndr n2, Data n1, Data n2) => Update (LHsBindLR n1 n2) t instance (Data t, OutputableBndr n, Data n) => Update (LHsType n) t instance (Data t, OutputableBndr n, Data n) => Update (LPat n) t instance (Data t, OutputableBndr n, Data n) => Update (Located (HsExpr n)) t module Language.Haskell.Refact.DupDef -- | This refactoring duplicates a definition (function binding or simple -- pattern binding) at the same level with a new name provided by the -- user. The new name should not cause name clash/capture. duplicateDef :: RefactSettings -> Cradle -> FilePath -> String -> SimpPos -> IO [FilePath] module Language.Haskell.Refact.MoveDef -- | Lift a definition to the top level liftToTopLevel :: RefactSettings -> Cradle -> FilePath -> SimpPos -> IO [FilePath] -- | Move a definition one level up from where it is now liftOneLevel :: RefactSettings -> Cradle -> FilePath -> SimpPos -> IO [FilePath] -- | Move a definition one level down demote :: RefactSettings -> Cradle -> FilePath -> SimpPos -> IO [FilePath] module Language.Haskell.Refact.Renaming -- | Rename the given identifier. rename :: RefactSettings -> Cradle -> FilePath -> String -> SimpPos -> IO [FilePath] module Language.Haskell.Refact.SwapArgs swapArgs :: RefactSettings -> Cradle -> [String] -> IO [FilePath] module Language.Haskell.Refact.Case -- | Convert an if expression to a case expression ifToCase :: RefactSettings -> Cradle -> FilePath -> SimpPos -> SimpPos -> IO [FilePath]