Embrace -XTypeInType, add -XStarIsType
[ghc.git] / compiler / basicTypes / SrcLoc.hs
1 -- (c) The University of Glasgow, 1992-2006
2
3 {-# LANGUAGE DeriveDataTypeable #-}
4 {-# LANGUAGE StandaloneDeriving #-}
5 {-# LANGUAGE DeriveFunctor #-}
6 {-# LANGUAGE DeriveFoldable #-}
7 {-# LANGUAGE DeriveTraversable #-}
8 {-# LANGUAGE FlexibleInstances #-}
9 {-# LANGUAGE RecordWildCards #-}
10
11 -- | This module contains types that relate to the positions of things
12 -- in source files, and allow tagging of those things with locations
13 module SrcLoc (
14 -- * SrcLoc
15 RealSrcLoc, -- Abstract
16 SrcLoc(..),
17
18 -- ** Constructing SrcLoc
19 mkSrcLoc, mkRealSrcLoc, mkGeneralSrcLoc,
20
21 noSrcLoc, -- "I'm sorry, I haven't a clue"
22 generatedSrcLoc, -- Code generated within the compiler
23 interactiveSrcLoc, -- Code from an interactive session
24
25 advanceSrcLoc,
26
27 -- ** Unsafely deconstructing SrcLoc
28 -- These are dubious exports, because they crash on some inputs
29 srcLocFile, -- return the file name part
30 srcLocLine, -- return the line part
31 srcLocCol, -- return the column part
32
33 -- * SrcSpan
34 RealSrcSpan, -- Abstract
35 SrcSpan(..),
36
37 -- ** Constructing SrcSpan
38 mkGeneralSrcSpan, mkSrcSpan, mkRealSrcSpan,
39 noSrcSpan,
40 wiredInSrcSpan, -- Something wired into the compiler
41 interactiveSrcSpan,
42 srcLocSpan, realSrcLocSpan,
43 combineSrcSpans,
44 srcSpanFirstCharacter,
45
46 -- ** Deconstructing SrcSpan
47 srcSpanStart, srcSpanEnd,
48 realSrcSpanStart, realSrcSpanEnd,
49 srcSpanFileName_maybe,
50 pprUserRealSpan,
51
52 -- ** Unsafely deconstructing SrcSpan
53 -- These are dubious exports, because they crash on some inputs
54 srcSpanFile,
55 srcSpanStartLine, srcSpanEndLine,
56 srcSpanStartCol, srcSpanEndCol,
57
58 -- ** Predicates on SrcSpan
59 isGoodSrcSpan, isOneLineSpan,
60 containsSpan,
61
62 -- * Located
63 Located,
64 RealLocated,
65 GenLocated(..),
66
67 -- ** Constructing Located
68 noLoc,
69 mkGeneralLocated,
70
71 -- ** Deconstructing Located
72 getLoc, unLoc,
73
74 -- ** Combining and comparing Located values
75 eqLocated, cmpLocated, combineLocs, addCLoc,
76 leftmost_smallest, leftmost_largest, rightmost,
77 spans, isSubspanOf, sortLocated
78 ) where
79
80 import GhcPrelude
81
82 import Util
83 import Json
84 import Outputable
85 import FastString
86
87 import Control.DeepSeq
88 import Data.Bits
89 import Data.Data
90 import Data.List
91 import Data.Ord
92
93 {-
94 ************************************************************************
95 * *
96 \subsection[SrcLoc-SrcLocations]{Source-location information}
97 * *
98 ************************************************************************
99
100 We keep information about the {\em definition} point for each entity;
101 this is the obvious stuff:
102 -}
103
104 -- | Real Source Location
105 --
106 -- Represents a single point within a file
107 data RealSrcLoc
108 = SrcLoc FastString -- A precise location (file name)
109 {-# UNPACK #-} !Int -- line number, begins at 1
110 {-# UNPACK #-} !Int -- column number, begins at 1
111 deriving (Eq, Ord)
112
113 -- | Source Location
114 data SrcLoc
115 = RealSrcLoc {-# UNPACK #-}!RealSrcLoc
116 | UnhelpfulLoc FastString -- Just a general indication
117 deriving (Eq, Ord, Show)
118
119 {-
120 ************************************************************************
121 * *
122 \subsection[SrcLoc-access-fns]{Access functions}
123 * *
124 ************************************************************************
125 -}
126
127 mkSrcLoc :: FastString -> Int -> Int -> SrcLoc
128 mkSrcLoc x line col = RealSrcLoc (mkRealSrcLoc x line col)
129
130 mkRealSrcLoc :: FastString -> Int -> Int -> RealSrcLoc
131 mkRealSrcLoc x line col = SrcLoc x line col
132
133 -- | Built-in "bad" 'SrcLoc' values for particular locations
134 noSrcLoc, generatedSrcLoc, interactiveSrcLoc :: SrcLoc
135 noSrcLoc = UnhelpfulLoc (fsLit "<no location info>")
136 generatedSrcLoc = UnhelpfulLoc (fsLit "<compiler-generated code>")
137 interactiveSrcLoc = UnhelpfulLoc (fsLit "<interactive>")
138
139 -- | Creates a "bad" 'SrcLoc' that has no detailed information about its location
140 mkGeneralSrcLoc :: FastString -> SrcLoc
141 mkGeneralSrcLoc = UnhelpfulLoc
142
143 -- | Gives the filename of the 'RealSrcLoc'
144 srcLocFile :: RealSrcLoc -> FastString
145 srcLocFile (SrcLoc fname _ _) = fname
146
147 -- | Raises an error when used on a "bad" 'SrcLoc'
148 srcLocLine :: RealSrcLoc -> Int
149 srcLocLine (SrcLoc _ l _) = l
150
151 -- | Raises an error when used on a "bad" 'SrcLoc'
152 srcLocCol :: RealSrcLoc -> Int
153 srcLocCol (SrcLoc _ _ c) = c
154
155 -- | Move the 'SrcLoc' down by one line if the character is a newline,
156 -- to the next 8-char tabstop if it is a tab, and across by one
157 -- character in any other case
158 advanceSrcLoc :: RealSrcLoc -> Char -> RealSrcLoc
159 advanceSrcLoc (SrcLoc f l _) '\n' = SrcLoc f (l + 1) 1
160 advanceSrcLoc (SrcLoc f l c) '\t' = SrcLoc f l (((((c - 1) `shiftR` 3) + 1)
161 `shiftL` 3) + 1)
162 advanceSrcLoc (SrcLoc f l c) _ = SrcLoc f l (c + 1)
163
164 {-
165 ************************************************************************
166 * *
167 \subsection[SrcLoc-instances]{Instance declarations for various names}
168 * *
169 ************************************************************************
170 -}
171
172 sortLocated :: [Located a] -> [Located a]
173 sortLocated things = sortBy (comparing getLoc) things
174
175 instance Outputable RealSrcLoc where
176 ppr (SrcLoc src_path src_line src_col)
177 = hcat [ pprFastFilePath src_path <> colon
178 , int src_line <> colon
179 , int src_col ]
180
181 -- I don't know why there is this style-based difference
182 -- if userStyle sty || debugStyle sty then
183 -- hcat [ pprFastFilePath src_path, char ':',
184 -- int src_line,
185 -- char ':', int src_col
186 -- ]
187 -- else
188 -- hcat [text "{-# LINE ", int src_line, space,
189 -- char '\"', pprFastFilePath src_path, text " #-}"]
190
191 instance Outputable SrcLoc where
192 ppr (RealSrcLoc l) = ppr l
193 ppr (UnhelpfulLoc s) = ftext s
194
195 instance Data RealSrcSpan where
196 -- don't traverse?
197 toConstr _ = abstractConstr "RealSrcSpan"
198 gunfold _ _ = error "gunfold"
199 dataTypeOf _ = mkNoRepType "RealSrcSpan"
200
201 instance Data SrcSpan where
202 -- don't traverse?
203 toConstr _ = abstractConstr "SrcSpan"
204 gunfold _ _ = error "gunfold"
205 dataTypeOf _ = mkNoRepType "SrcSpan"
206
207 {-
208 ************************************************************************
209 * *
210 \subsection[SrcSpan]{Source Spans}
211 * *
212 ************************************************************************
213 -}
214
215 {- |
216 A 'RealSrcSpan' delimits a portion of a text file. It could be represented
217 by a pair of (line,column) coordinates, but in fact we optimise
218 slightly by using more compact representations for single-line and
219 zero-length spans, both of which are quite common.
220
221 The end position is defined to be the column /after/ the end of the
222 span. That is, a span of (1,1)-(1,2) is one character long, and a
223 span of (1,1)-(1,1) is zero characters long.
224 -}
225
226 -- | Real Source Span
227 data RealSrcSpan
228 = RealSrcSpan'
229 { srcSpanFile :: !FastString,
230 srcSpanSLine :: {-# UNPACK #-} !Int,
231 srcSpanSCol :: {-# UNPACK #-} !Int,
232 srcSpanELine :: {-# UNPACK #-} !Int,
233 srcSpanECol :: {-# UNPACK #-} !Int
234 }
235 deriving Eq
236
237 -- | Source Span
238 --
239 -- A 'SrcSpan' identifies either a specific portion of a text file
240 -- or a human-readable description of a location.
241 data SrcSpan =
242 RealSrcSpan !RealSrcSpan
243 | UnhelpfulSpan !FastString -- Just a general indication
244 -- also used to indicate an empty span
245
246 deriving (Eq, Ord, Show) -- Show is used by Lexer.x, because we
247 -- derive Show for Token
248
249 instance ToJson SrcSpan where
250 json (UnhelpfulSpan {} ) = JSNull --JSObject [( "type", "unhelpful")]
251 json (RealSrcSpan rss) = json rss
252
253 instance ToJson RealSrcSpan where
254 json (RealSrcSpan'{..}) = JSObject [ ("file", JSString (unpackFS srcSpanFile))
255 , ("startLine", JSInt srcSpanSLine)
256 , ("startCol", JSInt srcSpanSCol)
257 , ("endLine", JSInt srcSpanELine)
258 , ("endCol", JSInt srcSpanECol)
259 ]
260
261 instance NFData SrcSpan where
262 rnf x = x `seq` ()
263
264 -- | Built-in "bad" 'SrcSpan's for common sources of location uncertainty
265 noSrcSpan, wiredInSrcSpan, interactiveSrcSpan :: SrcSpan
266 noSrcSpan = UnhelpfulSpan (fsLit "<no location info>")
267 wiredInSrcSpan = UnhelpfulSpan (fsLit "<wired into compiler>")
268 interactiveSrcSpan = UnhelpfulSpan (fsLit "<interactive>")
269
270 -- | Create a "bad" 'SrcSpan' that has not location information
271 mkGeneralSrcSpan :: FastString -> SrcSpan
272 mkGeneralSrcSpan = UnhelpfulSpan
273
274 -- | Create a 'SrcSpan' corresponding to a single point
275 srcLocSpan :: SrcLoc -> SrcSpan
276 srcLocSpan (UnhelpfulLoc str) = UnhelpfulSpan str
277 srcLocSpan (RealSrcLoc l) = RealSrcSpan (realSrcLocSpan l)
278
279 realSrcLocSpan :: RealSrcLoc -> RealSrcSpan
280 realSrcLocSpan (SrcLoc file line col) = RealSrcSpan' file line col line col
281
282 -- | Create a 'SrcSpan' between two points in a file
283 mkRealSrcSpan :: RealSrcLoc -> RealSrcLoc -> RealSrcSpan
284 mkRealSrcSpan loc1 loc2 = RealSrcSpan' file line1 col1 line2 col2
285 where
286 line1 = srcLocLine loc1
287 line2 = srcLocLine loc2
288 col1 = srcLocCol loc1
289 col2 = srcLocCol loc2
290 file = srcLocFile loc1
291
292 -- | 'True' if the span is known to straddle only one line.
293 isOneLineRealSpan :: RealSrcSpan -> Bool
294 isOneLineRealSpan (RealSrcSpan' _ line1 _ line2 _)
295 = line1 == line2
296
297 -- | 'True' if the span is a single point
298 isPointRealSpan :: RealSrcSpan -> Bool
299 isPointRealSpan (RealSrcSpan' _ line1 col1 line2 col2)
300 = line1 == line2 && col1 == col2
301
302 -- | Create a 'SrcSpan' between two points in a file
303 mkSrcSpan :: SrcLoc -> SrcLoc -> SrcSpan
304 mkSrcSpan (UnhelpfulLoc str) _ = UnhelpfulSpan str
305 mkSrcSpan _ (UnhelpfulLoc str) = UnhelpfulSpan str
306 mkSrcSpan (RealSrcLoc loc1) (RealSrcLoc loc2)
307 = RealSrcSpan (mkRealSrcSpan loc1 loc2)
308
309 -- | Combines two 'SrcSpan' into one that spans at least all the characters
310 -- within both spans. Assumes the "file" part is the same in both inputs
311 combineSrcSpans :: SrcSpan -> SrcSpan -> SrcSpan
312 combineSrcSpans (UnhelpfulSpan _) r = r -- this seems more useful
313 combineSrcSpans l (UnhelpfulSpan _) = l
314 combineSrcSpans (RealSrcSpan span1) (RealSrcSpan span2)
315 = RealSrcSpan (combineRealSrcSpans span1 span2)
316
317 -- | Combines two 'SrcSpan' into one that spans at least all the characters
318 -- within both spans. Assumes the "file" part is the same in both inputs
319 combineRealSrcSpans :: RealSrcSpan -> RealSrcSpan -> RealSrcSpan
320 combineRealSrcSpans span1 span2
321 = RealSrcSpan' file line_start col_start line_end col_end
322 where
323 (line_start, col_start) = min (srcSpanStartLine span1, srcSpanStartCol span1)
324 (srcSpanStartLine span2, srcSpanStartCol span2)
325 (line_end, col_end) = max (srcSpanEndLine span1, srcSpanEndCol span1)
326 (srcSpanEndLine span2, srcSpanEndCol span2)
327 file = srcSpanFile span1
328
329 -- | Convert a SrcSpan into one that represents only its first character
330 srcSpanFirstCharacter :: SrcSpan -> SrcSpan
331 srcSpanFirstCharacter l@(UnhelpfulSpan {}) = l
332 srcSpanFirstCharacter (RealSrcSpan span) = RealSrcSpan $ mkRealSrcSpan loc1 loc2
333 where
334 loc1@(SrcLoc f l c) = realSrcSpanStart span
335 loc2 = SrcLoc f l (c+1)
336
337 {-
338 ************************************************************************
339 * *
340 \subsection[SrcSpan-predicates]{Predicates}
341 * *
342 ************************************************************************
343 -}
344
345 -- | Test if a 'SrcSpan' is "good", i.e. has precise location information
346 isGoodSrcSpan :: SrcSpan -> Bool
347 isGoodSrcSpan (RealSrcSpan _) = True
348 isGoodSrcSpan (UnhelpfulSpan _) = False
349
350 isOneLineSpan :: SrcSpan -> Bool
351 -- ^ True if the span is known to straddle only one line.
352 -- For "bad" 'SrcSpan', it returns False
353 isOneLineSpan (RealSrcSpan s) = srcSpanStartLine s == srcSpanEndLine s
354 isOneLineSpan (UnhelpfulSpan _) = False
355
356 -- | Tests whether the first span "contains" the other span, meaning
357 -- that it covers at least as much source code. True where spans are equal.
358 containsSpan :: RealSrcSpan -> RealSrcSpan -> Bool
359 containsSpan s1 s2
360 = (srcSpanStartLine s1, srcSpanStartCol s1)
361 <= (srcSpanStartLine s2, srcSpanStartCol s2)
362 && (srcSpanEndLine s1, srcSpanEndCol s1)
363 >= (srcSpanEndLine s2, srcSpanEndCol s2)
364 && (srcSpanFile s1 == srcSpanFile s2)
365 -- We check file equality last because it is (presumably?) least
366 -- likely to fail.
367 {-
368 %************************************************************************
369 %* *
370 \subsection[SrcSpan-unsafe-access-fns]{Unsafe access functions}
371 * *
372 ************************************************************************
373 -}
374
375 srcSpanStartLine :: RealSrcSpan -> Int
376 srcSpanEndLine :: RealSrcSpan -> Int
377 srcSpanStartCol :: RealSrcSpan -> Int
378 srcSpanEndCol :: RealSrcSpan -> Int
379
380 srcSpanStartLine RealSrcSpan'{ srcSpanSLine=l } = l
381 srcSpanEndLine RealSrcSpan'{ srcSpanELine=l } = l
382 srcSpanStartCol RealSrcSpan'{ srcSpanSCol=l } = l
383 srcSpanEndCol RealSrcSpan'{ srcSpanECol=c } = c
384
385 {-
386 ************************************************************************
387 * *
388 \subsection[SrcSpan-access-fns]{Access functions}
389 * *
390 ************************************************************************
391 -}
392
393 -- | Returns the location at the start of the 'SrcSpan' or a "bad" 'SrcSpan' if that is unavailable
394 srcSpanStart :: SrcSpan -> SrcLoc
395 srcSpanStart (UnhelpfulSpan str) = UnhelpfulLoc str
396 srcSpanStart (RealSrcSpan s) = RealSrcLoc (realSrcSpanStart s)
397
398 -- | Returns the location at the end of the 'SrcSpan' or a "bad" 'SrcSpan' if that is unavailable
399 srcSpanEnd :: SrcSpan -> SrcLoc
400 srcSpanEnd (UnhelpfulSpan str) = UnhelpfulLoc str
401 srcSpanEnd (RealSrcSpan s) = RealSrcLoc (realSrcSpanEnd s)
402
403 realSrcSpanStart :: RealSrcSpan -> RealSrcLoc
404 realSrcSpanStart s = mkRealSrcLoc (srcSpanFile s)
405 (srcSpanStartLine s)
406 (srcSpanStartCol s)
407
408 realSrcSpanEnd :: RealSrcSpan -> RealSrcLoc
409 realSrcSpanEnd s = mkRealSrcLoc (srcSpanFile s)
410 (srcSpanEndLine s)
411 (srcSpanEndCol s)
412
413 -- | Obtains the filename for a 'SrcSpan' if it is "good"
414 srcSpanFileName_maybe :: SrcSpan -> Maybe FastString
415 srcSpanFileName_maybe (RealSrcSpan s) = Just (srcSpanFile s)
416 srcSpanFileName_maybe (UnhelpfulSpan _) = Nothing
417
418 {-
419 ************************************************************************
420 * *
421 \subsection[SrcSpan-instances]{Instances}
422 * *
423 ************************************************************************
424 -}
425
426 -- We want to order RealSrcSpans first by the start point, then by the
427 -- end point.
428 instance Ord RealSrcSpan where
429 a `compare` b =
430 (realSrcSpanStart a `compare` realSrcSpanStart b) `thenCmp`
431 (realSrcSpanEnd a `compare` realSrcSpanEnd b)
432
433 instance Show RealSrcLoc where
434 show (SrcLoc filename row col)
435 = "SrcLoc " ++ show filename ++ " " ++ show row ++ " " ++ show col
436
437 -- Show is used by Lexer.x, because we derive Show for Token
438 instance Show RealSrcSpan where
439 show span@(RealSrcSpan' file sl sc el ec)
440 | isPointRealSpan span
441 = "SrcSpanPoint " ++ show file ++ " " ++ intercalate " " (map show [sl,sc])
442
443 | isOneLineRealSpan span
444 = "SrcSpanOneLine " ++ show file ++ " "
445 ++ intercalate " " (map show [sl,sc,ec])
446
447 | otherwise
448 = "SrcSpanMultiLine " ++ show file ++ " "
449 ++ intercalate " " (map show [sl,sc,el,ec])
450
451
452 instance Outputable RealSrcSpan where
453 ppr span = pprUserRealSpan True span
454
455 -- I don't know why there is this style-based difference
456 -- = getPprStyle $ \ sty ->
457 -- if userStyle sty || debugStyle sty then
458 -- text (showUserRealSpan True span)
459 -- else
460 -- hcat [text "{-# LINE ", int (srcSpanStartLine span), space,
461 -- char '\"', pprFastFilePath $ srcSpanFile span, text " #-}"]
462
463 instance Outputable SrcSpan where
464 ppr span = pprUserSpan True span
465
466 -- I don't know why there is this style-based difference
467 -- = getPprStyle $ \ sty ->
468 -- if userStyle sty || debugStyle sty then
469 -- pprUserSpan True span
470 -- else
471 -- case span of
472 -- UnhelpfulSpan _ -> panic "Outputable UnhelpfulSpan"
473 -- RealSrcSpan s -> ppr s
474
475 pprUserSpan :: Bool -> SrcSpan -> SDoc
476 pprUserSpan _ (UnhelpfulSpan s) = ftext s
477 pprUserSpan show_path (RealSrcSpan s) = pprUserRealSpan show_path s
478
479 pprUserRealSpan :: Bool -> RealSrcSpan -> SDoc
480 pprUserRealSpan show_path span@(RealSrcSpan' src_path line col _ _)
481 | isPointRealSpan span
482 = hcat [ ppWhen show_path (pprFastFilePath src_path <> colon)
483 , int line <> colon
484 , int col ]
485
486 pprUserRealSpan show_path span@(RealSrcSpan' src_path line scol _ ecol)
487 | isOneLineRealSpan span
488 = hcat [ ppWhen show_path (pprFastFilePath src_path <> colon)
489 , int line <> colon
490 , int scol
491 , ppUnless (ecol - scol <= 1) (char '-' <> int (ecol - 1)) ]
492 -- For single-character or point spans, we just
493 -- output the starting column number
494
495 pprUserRealSpan show_path (RealSrcSpan' src_path sline scol eline ecol)
496 = hcat [ ppWhen show_path (pprFastFilePath src_path <> colon)
497 , parens (int sline <> comma <> int scol)
498 , char '-'
499 , parens (int eline <> comma <> int ecol') ]
500 where
501 ecol' = if ecol == 0 then ecol else ecol - 1
502
503 {-
504 ************************************************************************
505 * *
506 \subsection[Located]{Attaching SrcSpans to things}
507 * *
508 ************************************************************************
509 -}
510
511 -- | We attach SrcSpans to lots of things, so let's have a datatype for it.
512 data GenLocated l e = L l e
513 deriving (Eq, Ord, Data, Functor, Foldable, Traversable)
514
515 type Located = GenLocated SrcSpan
516 type RealLocated = GenLocated RealSrcSpan
517
518 unLoc :: GenLocated l e -> e
519 unLoc (L _ e) = e
520
521 getLoc :: GenLocated l e -> l
522 getLoc (L l _) = l
523
524 noLoc :: e -> Located e
525 noLoc e = L noSrcSpan e
526
527 mkGeneralLocated :: String -> e -> Located e
528 mkGeneralLocated s e = L (mkGeneralSrcSpan (fsLit s)) e
529
530 combineLocs :: Located a -> Located b -> SrcSpan
531 combineLocs a b = combineSrcSpans (getLoc a) (getLoc b)
532
533 -- | Combine locations from two 'Located' things and add them to a third thing
534 addCLoc :: Located a -> Located b -> c -> Located c
535 addCLoc a b c = L (combineSrcSpans (getLoc a) (getLoc b)) c
536
537 -- not clear whether to add a general Eq instance, but this is useful sometimes:
538
539 -- | Tests whether the two located things are equal
540 eqLocated :: Eq a => Located a -> Located a -> Bool
541 eqLocated a b = unLoc a == unLoc b
542
543 -- not clear whether to add a general Ord instance, but this is useful sometimes:
544
545 -- | Tests the ordering of the two located things
546 cmpLocated :: Ord a => Located a -> Located a -> Ordering
547 cmpLocated a b = unLoc a `compare` unLoc b
548
549 instance (Outputable l, Outputable e) => Outputable (GenLocated l e) where
550 ppr (L l e) = -- TODO: We can't do this since Located was refactored into
551 -- GenLocated:
552 -- Print spans without the file name etc
553 -- ifPprDebug (braces (pprUserSpan False l))
554 whenPprDebug (braces (ppr l))
555 $$ ppr e
556
557 {-
558 ************************************************************************
559 * *
560 \subsection{Ordering SrcSpans for InteractiveUI}
561 * *
562 ************************************************************************
563 -}
564
565 -- | Alternative strategies for ordering 'SrcSpan's
566 leftmost_smallest, leftmost_largest, rightmost :: SrcSpan -> SrcSpan -> Ordering
567 rightmost = flip compare
568 leftmost_smallest = compare
569 leftmost_largest a b = (srcSpanStart a `compare` srcSpanStart b)
570 `thenCmp`
571 (srcSpanEnd b `compare` srcSpanEnd a)
572
573 -- | Determines whether a span encloses a given line and column index
574 spans :: SrcSpan -> (Int, Int) -> Bool
575 spans (UnhelpfulSpan _) _ = panic "spans UnhelpfulSpan"
576 spans (RealSrcSpan span) (l,c) = realSrcSpanStart span <= loc && loc <= realSrcSpanEnd span
577 where loc = mkRealSrcLoc (srcSpanFile span) l c
578
579 -- | Determines whether a span is enclosed by another one
580 isSubspanOf :: SrcSpan -- ^ The span that may be enclosed by the other
581 -> SrcSpan -- ^ The span it may be enclosed by
582 -> Bool
583 isSubspanOf src parent
584 | srcSpanFileName_maybe parent /= srcSpanFileName_maybe src = False
585 | otherwise = srcSpanStart parent <= srcSpanStart src &&
586 srcSpanEnd parent >= srcSpanEnd src