@@ -9,13 +9,30 @@ Portability : portable
9
9
10
10
Everything to do with describing a position or a contiguous region in a file.
11
11
-}
12
- {-# LANGUAGE CPP, DeriveDataTypeable, DeriveGeneric, DeriveAnyClass #-}
12
+ {-# LANGUAGE CPP #-}
13
+ {-# LANGUAGE DeriveDataTypeable #-}
14
+ {-# LANGUAGE DeriveGeneric #-}
15
+ {-# LANGUAGE DeriveAnyClass #-}
13
16
14
17
module Language.Rust.Data.Position (
15
18
-- * Positions in files
16
- Position (.. ), prettyPosition , maxPos , minPos , initPos , incPos , retPos , incOffset ,
19
+ Position (.. ),
20
+ prettyPosition ,
21
+ maxPos ,
22
+ minPos ,
23
+ initPos ,
24
+ incPos ,
25
+ retPos ,
26
+ incOffset ,
27
+
17
28
-- * Spans in files
18
- Span (.. ), prettySpan , subsetOf , (#) , Spanned (.. ), Located (.. ),
29
+ Span (.. ),
30
+ unspan ,
31
+ prettySpan ,
32
+ subsetOf ,
33
+ (#) ,
34
+ Spanned (.. ),
35
+ Located (.. ),
19
36
) where
20
37
21
38
import GHC.Generics (Generic )
@@ -24,8 +41,6 @@ import Data.Data (Data)
24
41
import Data.Typeable (Typeable )
25
42
import Control.DeepSeq (NFData )
26
43
27
- import Data.Ord (comparing )
28
- import Data.List (maximumBy , minimumBy )
29
44
import Data.List.NonEmpty (NonEmpty (.. ))
30
45
import Data.Monoid (Monoid (.. ))
31
46
import Data.Semigroup (Semigroup (.. ))
@@ -43,7 +58,7 @@ data Position = Position {
43
58
44
59
-- | Pretty print a 'Position'
45
60
prettyPosition :: Position -> String
46
- prettyPosition NoPosition = " $ "
61
+ prettyPosition NoPosition = " ??? "
47
62
prettyPosition (Position _ r c) = show r ++ " :" ++ show c
48
63
49
64
-- | Maximum of two positions, bias for actual positions.
@@ -54,10 +69,11 @@ prettyPosition (Position _ r c) = show r ++ ":" ++ show c
54
69
-- >>> maxPos NoPosition (Position 30 5 8)
55
70
-- Position 30 5 8
56
71
--
72
+ {-# INLINE maxPos #-}
57
73
maxPos :: Position -> Position -> Position
58
74
maxPos NoPosition p2 = p2
59
75
maxPos p1 NoPosition = p1
60
- maxPos p1 p2 = maximumBy (comparing absoluteOffset) [p1,p2]
76
+ maxPos p1@ ( Position a1 _ _) p2 @ ( Position a2 _ _) = if a1 > a2 then p1 else p2
61
77
62
78
-- | Maximum and minimum positions, bias for actual positions.
63
79
--
@@ -67,69 +83,84 @@ maxPos p1 p2 = maximumBy (comparing absoluteOffset) [p1,p2]
67
83
-- >>> minPos NoPosition (Position 30 5 8)
68
84
-- Position 30 5 8
69
85
--
86
+ {-# INLINE minPos #-}
70
87
minPos :: Position -> Position -> Position
71
88
minPos NoPosition p2 = p2
72
89
minPos p1 NoPosition = p1
73
- minPos p1 p2 = minimumBy (comparing absoluteOffset) [p1,p2]
90
+ minPos p1@ ( Position a1 _ _) p2 @ ( Position a2 _ _) = if a1 < a2 then p1 else p2
74
91
75
92
-- | Starting position in a file.
93
+ {-# INLINE initPos #-}
76
94
initPos :: Position
77
95
initPos = Position 0 1 0
78
96
79
97
-- | Advance columnn a certain number of times.
98
+ {-# INLINE incPos #-}
80
99
incPos :: Position -> Int -> Position
81
100
incPos NoPosition _ = NoPosition
82
101
incPos p@ Position { absoluteOffset = a, col = c } offset = p { absoluteOffset = a + offset, col = c + offset }
83
102
84
103
-- | Advance to the next line.
104
+ {-# INLINE retPos #-}
85
105
retPos :: Position -> Position
86
106
retPos NoPosition = NoPosition
87
107
retPos (Position a r _) = Position { absoluteOffset = a + 1 , row = r + 1 , col = 1 }
88
108
89
109
-- | Advance only the absolute offset, not the row and column information. Only use this if you
90
110
-- know what you are doing!
111
+ {-# INLINE incOffset #-}
91
112
incOffset :: Position -> Int -> Position
92
113
incOffset NoPosition _ = NoPosition
93
114
incOffset p@ Position { absoluteOffset = a } offset = p { absoluteOffset = a + offset }
94
115
95
116
-- | Spans represent a contiguous region of code, delimited by two 'Position's. The endpoints are
96
117
-- inclusive. Analogous to the information encoded in a selection.
97
- data Span = Span {
98
- #if __GLASGOW_HASKELL__ >= 820
99
- lo , hi :: {-# UNPACK #-} ! Position
100
- # else
101
- lo , hi :: ! Position
102
- # endif
103
- } deriving (Eq , Show , Data , Typeable , Generic , NFData )
118
+ data Span = Span { lo , hi :: ! Position }
119
+ deriving (Eq , Show , Data , Typeable , Generic , NFData )
104
120
105
121
-- | Check if a span is a subset of another span
106
122
subsetOf :: Span -> Span -> Bool
107
123
Span l1 h1 `subsetOf` Span l2 h2 = minPos l1 l2 == l1 && maxPos h1 h2 == h2
108
124
109
125
-- | Convenience function lifting '<>' to work on all 'Located' things
126
+ {-# INLINE (#) #-}
110
127
(#) :: (Located a , Located b ) => a -> b -> Span
111
128
left # right = spanOf left <> spanOf right
112
129
113
130
-- | smallest covering 'Span'
114
131
instance Semigroup Span where
115
- Span l1 h1 <> Span l2 h2 = Span (minPos l1 l2) (maxPos h1 h2)
132
+ {-# INLINE (<>) #-}
133
+ Span l1 h1 <> Span l2 h2 = Span (l1 `minPos` l2) (h1 `maxPos` h2)
116
134
117
135
instance Monoid Span where
136
+ {-# INLINE mempty #-}
118
137
mempty = Span NoPosition NoPosition
138
+
139
+ {-# INLINE mappend #-}
119
140
mappend = (<>)
120
141
121
142
-- | Pretty print a 'Span'
122
143
prettySpan :: Span -> String
123
144
prettySpan (Span lo' hi') = show lo' ++ " - " ++ show hi'
124
145
125
146
-- | A "tagging" of something with a 'Span' that describes its extent.
126
- data Spanned a = Spanned { unspan :: a , span :: {-# UNPACK #-} ! Span } deriving (Data , Typeable , Generic , NFData )
147
+ data Spanned a = Spanned a {- # UNPACK #-} !Span
148
+ deriving (Data , Typeable , Generic , NFData )
149
+
150
+ -- | Extract the wrapped value from 'Spanned'
151
+ {-# INLINE unspan #-}
152
+ unspan :: Spanned a -> a
153
+ unspan (Spanned x _) = x
127
154
128
155
instance Functor Spanned where
156
+ {-# INLINE fmap #-}
129
157
fmap f (Spanned x s) = Spanned (f x) s
130
158
131
159
instance Applicative Spanned where
160
+ {-# INLINE pure #-}
132
161
pure x = Spanned x mempty
162
+
163
+ {-# INLINE (<*>) #-}
133
164
Spanned f s1 <*> Spanned x s2 = Spanned (f x) (s1 <> s2)
134
165
135
166
instance Monad Spanned where
@@ -149,18 +180,25 @@ class Located a where
149
180
spanOf :: a -> Span
150
181
151
182
instance Located Span where
183
+ {-# INLINE spanOf #-}
152
184
spanOf = id
153
185
154
186
instance Located (Spanned a ) where
187
+ {-# INLINE spanOf #-}
155
188
spanOf (Spanned _ s) = s
156
189
157
190
instance Located a => Located (Maybe a ) where
191
+ {-# INLINE spanOf #-}
158
192
spanOf = foldMap spanOf
159
193
194
+ -- | /O(n)/ time complexity
160
195
instance Located a => Located [a ] where
196
+ {-# INLINE spanOf #-}
161
197
spanOf = foldMap spanOf
162
198
199
+ -- | /O(n)/ time complexity
163
200
instance Located a => Located (NonEmpty a ) where
201
+ {-# INLINE spanOf #-}
164
202
spanOf = foldMap spanOf
165
203
166
204
0 commit comments