module Language.Haskell.Formatter.Location
(SrcLoc.SrcLoc, SrcLoc.SrcSpan, SrcLoc.SrcSpanInfo, base, plus, minus,
Portioned(..), Line, Column, streamName, getLine, getColumn,
createPosition, SrcLoc.getPointLoc, getEndPosition,
replaceNestedPortionLines, stringPortion, getStartLine, getStartColumn,
getEndLine, getEndColumn)
where
import qualified Data.Function as Function
import qualified Language.Haskell.Exts.Comments as Comments
import qualified Language.Haskell.Exts.SrcLoc as SrcLoc
import qualified Language.Haskell.Exts.Syntax as Syntax
import qualified Language.Haskell.Formatter.Internal.Newline as Newline
import qualified Language.Haskell.Formatter.Toolkit.ListTool as ListTool
import qualified Language.Haskell.Formatter.Toolkit.StreamName as StreamName
import Prelude hiding (getLine)
class Enum a => Natural a where
base :: a
plus :: Integral b => b -> a -> a
plus b
difference a
natural
= Int -> a
forall a. Enum a => Int -> a
toEnum (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
difference Int -> Int -> Int
forall a. Num a => a -> a -> a
+ a -> Int
forall a. Enum a => a -> Int
fromEnum a
natural
minus :: Num b => a -> a -> b
minus a
minuend = Int -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> b) -> (a -> Int) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Int) -> (a -> Int) -> a -> a -> Int
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
Function.on (-) a -> Int
forall a. Enum a => a -> Int
fromEnum a
minuend
class Portioned a where
getPortion :: a -> SrcLoc.SrcSpan
newtype Line = Line Int
deriving (Line -> Line -> Bool
(Line -> Line -> Bool) -> (Line -> Line -> Bool) -> Eq Line
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Line -> Line -> Bool
$c/= :: Line -> Line -> Bool
== :: Line -> Line -> Bool
$c== :: Line -> Line -> Bool
Eq, Eq Line
Eq Line
-> (Line -> Line -> Ordering)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Line)
-> (Line -> Line -> Line)
-> Ord Line
Line -> Line -> Bool
Line -> Line -> Ordering
Line -> Line -> Line
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Line -> Line -> Line
$cmin :: Line -> Line -> Line
max :: Line -> Line -> Line
$cmax :: Line -> Line -> Line
>= :: Line -> Line -> Bool
$c>= :: Line -> Line -> Bool
> :: Line -> Line -> Bool
$c> :: Line -> Line -> Bool
<= :: Line -> Line -> Bool
$c<= :: Line -> Line -> Bool
< :: Line -> Line -> Bool
$c< :: Line -> Line -> Bool
compare :: Line -> Line -> Ordering
$ccompare :: Line -> Line -> Ordering
$cp1Ord :: Eq Line
Ord, Int -> Line -> ShowS
[Line] -> ShowS
Line -> String
(Int -> Line -> ShowS)
-> (Line -> String) -> ([Line] -> ShowS) -> Show Line
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Line] -> ShowS
$cshowList :: [Line] -> ShowS
show :: Line -> String
$cshow :: Line -> String
showsPrec :: Int -> Line -> ShowS
$cshowsPrec :: Int -> Line -> ShowS
Show)
newtype Column = Column Int
deriving (Column -> Column -> Bool
(Column -> Column -> Bool)
-> (Column -> Column -> Bool) -> Eq Column
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Column -> Column -> Bool
$c/= :: Column -> Column -> Bool
== :: Column -> Column -> Bool
$c== :: Column -> Column -> Bool
Eq, Eq Column
Eq Column
-> (Column -> Column -> Ordering)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Column)
-> (Column -> Column -> Column)
-> Ord Column
Column -> Column -> Bool
Column -> Column -> Ordering
Column -> Column -> Column
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Column -> Column -> Column
$cmin :: Column -> Column -> Column
max :: Column -> Column -> Column
$cmax :: Column -> Column -> Column
>= :: Column -> Column -> Bool
$c>= :: Column -> Column -> Bool
> :: Column -> Column -> Bool
$c> :: Column -> Column -> Bool
<= :: Column -> Column -> Bool
$c<= :: Column -> Column -> Bool
< :: Column -> Column -> Bool
$c< :: Column -> Column -> Bool
compare :: Column -> Column -> Ordering
$ccompare :: Column -> Column -> Ordering
$cp1Ord :: Eq Column
Ord, Int -> Column -> ShowS
[Column] -> ShowS
Column -> String
(Int -> Column -> ShowS)
-> (Column -> String) -> ([Column] -> ShowS) -> Show Column
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Column] -> ShowS
$cshowList :: [Column] -> ShowS
show :: Column -> String
$cshow :: Column -> String
showsPrec :: Int -> Column -> ShowS
$cshowsPrec :: Int -> Column -> ShowS
Show)
instance Enum Line where
toEnum :: Int -> Line
toEnum = Int -> Line
Line
fromEnum :: Line -> Int
fromEnum (Line Int
line) = Int
line
instance Enum Column where
toEnum :: Int -> Column
toEnum = Int -> Column
Column
fromEnum :: Column -> Int
fromEnum (Column Int
column) = Int
column
instance Natural Line where
base :: Line
base = Int -> Line
Line Int
1
instance Natural Column where
base :: Column
base = Int -> Column
Column Int
1
instance Portioned SrcLoc.SrcSpanInfo where
getPortion :: SrcSpanInfo -> SrcSpan
getPortion = SrcSpanInfo -> SrcSpan
SrcLoc.srcInfoSpan
instance Portioned a => Portioned (Syntax.Module a) where
getPortion :: Module a -> SrcSpan
getPortion = a -> SrcSpan
forall a. Portioned a => a -> SrcSpan
getPortion (a -> SrcSpan) -> (Module a -> a) -> Module a -> SrcSpan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Module a -> a
forall (ast :: * -> *) l. Annotated ast => ast l -> l
Syntax.ann
instance Portioned Comments.Comment where
getPortion :: Comment -> SrcSpan
getPortion (Comments.Comment Bool
_ SrcSpan
commentPortion String
_) = SrcSpan
commentPortion
streamName :: SrcLoc.SrcInfo a => a -> StreamName.StreamName
streamName :: a -> StreamName
streamName = String -> StreamName
StreamName.createStreamName (String -> StreamName) -> (a -> String) -> a -> StreamName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall si. SrcInfo si => si -> String
SrcLoc.fileName
getLine :: SrcLoc.SrcLoc -> Line
getLine :: SrcLoc -> Line
getLine = Int -> Line
Line (Int -> Line) -> (SrcLoc -> Int) -> SrcLoc -> Line
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcLoc -> Int
SrcLoc.srcLine
getColumn :: SrcLoc.SrcLoc -> Column
getColumn :: SrcLoc -> Column
getColumn = Int -> Column
Column (Int -> Column) -> (SrcLoc -> Int) -> SrcLoc -> Column
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcLoc -> Int
SrcLoc.srcColumn
createPosition :: StreamName.StreamName -> Line -> Column -> SrcLoc.SrcLoc
createPosition :: StreamName -> Line -> Column -> SrcLoc
createPosition StreamName
stream (Line Int
line) (Column Int
column)
= SrcLoc :: String -> Int -> Int -> SrcLoc
SrcLoc.SrcLoc{srcFilename :: String
SrcLoc.srcFilename = StreamName -> String
forall a. Show a => a -> String
show StreamName
stream, srcLine :: Int
SrcLoc.srcLine = Int
line,
srcColumn :: Int
SrcLoc.srcColumn = Int
column}
getEndPosition :: SrcLoc.SrcSpan -> SrcLoc.SrcLoc
getEndPosition :: SrcSpan -> SrcLoc
getEndPosition SrcSpan
portion = StreamName -> Line -> Column -> SrcLoc
createPosition StreamName
stream Line
line Column
column
where stream :: StreamName
stream = SrcSpan -> StreamName
forall a. SrcInfo a => a -> StreamName
streamName SrcSpan
portion
line :: Line
line = Int -> Line
Line (Int -> Line) -> Int -> Line
forall a b. (a -> b) -> a -> b
$ SrcSpan -> Int
SrcLoc.srcSpanEndLine SrcSpan
portion
column :: Column
column = Int -> Column
Column (Int -> Column) -> Int -> Column
forall a b. (a -> b) -> a -> b
$ SrcSpan -> Int
SrcLoc.srcSpanEndColumn SrcSpan
portion
replaceNestedPortionLines ::
(Line -> Line) ->
SrcLoc.SrcSpanInfo -> SrcLoc.SrcSpanInfo
replaceNestedPortionLines :: (Line -> Line) -> SrcSpanInfo -> SrcSpanInfo
replaceNestedPortionLines Line -> Line
function SrcSpanInfo
nestedPortion
= SrcSpanInfo
nestedPortion{srcInfoSpan :: SrcSpan
SrcLoc.srcInfoSpan = SrcSpan
parent',
srcInfoPoints :: [SrcSpan]
SrcLoc.srcInfoPoints = [SrcSpan]
children'}
where parent' :: SrcSpan
parent' = SrcSpan -> SrcSpan
replace SrcSpan
parent
replace :: SrcSpan -> SrcSpan
replace = (Line -> Line) -> SrcSpan -> SrcSpan
replacePortionLines Line -> Line
function
parent :: SrcSpan
parent = SrcSpanInfo -> SrcSpan
SrcLoc.srcInfoSpan SrcSpanInfo
nestedPortion
children' :: [SrcSpan]
children' = (SrcSpan -> SrcSpan) -> [SrcSpan] -> [SrcSpan]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SrcSpan -> SrcSpan
replace [SrcSpan]
children
children :: [SrcSpan]
children = SrcSpanInfo -> [SrcSpan]
SrcLoc.srcInfoPoints SrcSpanInfo
nestedPortion
replacePortionLines :: (Line -> Line) -> SrcLoc.SrcSpan -> SrcLoc.SrcSpan
replacePortionLines :: (Line -> Line) -> SrcSpan -> SrcSpan
replacePortionLines Line -> Line
function SrcSpan
portion
= SrcSpan
portion{srcSpanStartLine :: Int
SrcLoc.srcSpanStartLine = Int
start, srcSpanEndLine :: Int
SrcLoc.srcSpanEndLine = Int
end}
where Line Int
start = Line -> Line
function (Line -> Line) -> Line -> Line
forall a b. (a -> b) -> a -> b
$ SrcSpan -> Line
forall a. SrcInfo a => a -> Line
getStartLine SrcSpan
portion
Line Int
end = Line -> Line
function (Line -> Line) -> Line -> Line
forall a b. (a -> b) -> a -> b
$ SrcSpan -> Line
getEndLine SrcSpan
portion
stringPortion :: SrcLoc.SrcLoc -> String -> SrcLoc.SrcSpan
stringPortion :: SrcLoc -> String -> SrcSpan
stringPortion SrcLoc
startPosition String
string = SrcLoc -> SrcLoc -> SrcSpan
SrcLoc.mkSrcSpan SrcLoc
startPosition SrcLoc
endPosition
where endPosition :: SrcLoc
endPosition = StreamName -> Line -> Column -> SrcLoc
createPosition StreamName
stream Line
endLine Column
endColumn
stream :: StreamName
stream = SrcLoc -> StreamName
forall a. SrcInfo a => a -> StreamName
streamName SrcLoc
startPosition
endLine :: Line
endLine = Int -> Line -> Line
forall c b. (Natural c, Integral b) => b -> c -> c
lastIndex Int
lineCount Line
startLine
lastIndex :: b -> c -> c
lastIndex b
difference = c -> c
forall a. Enum a => a -> a
pred (c -> c) -> (c -> c) -> c -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> c -> c
forall a b. (Natural a, Integral b) => b -> a -> a
plus b
difference
lineCount :: Int
lineCount = [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
stringLines
stringLines :: [String]
stringLines = String -> [String]
Newline.splitSeparatedLines String
string
startLine :: Line
startLine = SrcLoc -> Line
forall a. SrcInfo a => a -> Line
getStartLine SrcLoc
startPosition
endColumn :: Column
endColumn = Int -> Column -> Column
forall c b. (Natural c, Integral b) => b -> c -> c
lastIndex Int
lastLineLength Column
lastLineStartColumn
lastLineLength :: Int
lastLineLength = Int -> (String -> Int) -> Maybe String -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Maybe String -> Int) -> Maybe String -> Int
forall a b. (a -> b) -> a -> b
$ [String] -> Maybe String
forall a. [a] -> Maybe a
ListTool.maybeLast [String]
stringLines
lastLineStartColumn :: Column
lastLineStartColumn = if Bool
hasSingleLine then Column
startColumn else Column
forall a. Natural a => a
base
hasSingleLine :: Bool
hasSingleLine = Int
lineCount Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
startColumn :: Column
startColumn = SrcLoc -> Column
forall a. SrcInfo a => a -> Column
getStartColumn SrcLoc
startPosition
getStartLine :: SrcLoc.SrcInfo a => a -> Line
getStartLine :: a -> Line
getStartLine = SrcLoc -> Line
getLine (SrcLoc -> Line) -> (a -> SrcLoc) -> a -> Line
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SrcLoc
forall si. SrcInfo si => si -> SrcLoc
SrcLoc.getPointLoc
getStartColumn :: SrcLoc.SrcInfo a => a -> Column
getStartColumn :: a -> Column
getStartColumn = SrcLoc -> Column
getColumn (SrcLoc -> Column) -> (a -> SrcLoc) -> a -> Column
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SrcLoc
forall si. SrcInfo si => si -> SrcLoc
SrcLoc.getPointLoc
getEndLine :: SrcLoc.SrcSpan -> Line
getEndLine :: SrcSpan -> Line
getEndLine = SrcLoc -> Line
getLine (SrcLoc -> Line) -> (SrcSpan -> SrcLoc) -> SrcSpan -> Line
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpan -> SrcLoc
getEndPosition
getEndColumn :: SrcLoc.SrcSpan -> Column
getEndColumn :: SrcSpan -> Column
getEndColumn = SrcLoc -> Column
getColumn (SrcLoc -> Column) -> (SrcSpan -> SrcLoc) -> SrcSpan -> Column
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpan -> SrcLoc
getEndPosition