%
-% (c) The University of Glasgow, 1992-2003
+% (c) The University of Glasgow, 1992-2006
%
-%************************************************************************
-%* *
-\section[SrcLoc]{The @SrcLoc@ type}
-%* *
-%************************************************************************
\begin{code}
module SrcLoc (
advanceSrcLoc,
importedSrcLoc, -- Unknown place in an interface
- wiredInSrcLoc, -- Something wired into the compiler
generatedSrcLoc, -- Code generated within the compiler
interactiveSrcLoc, -- Code from an interactive session
pprDefnLoc,
SrcSpan, -- Abstract
- noSrcSpan,
+ noSrcSpan,
+ wiredInSrcSpan, -- Something wired into the compiler
+ importedSrcSpan, -- Unknown place in an interface
mkGeneralSrcSpan,
- isGoodSrcSpan,
+ isGoodSrcSpan, isOneLineSpan,
mkSrcSpan, srcLocSpan,
combineSrcSpans,
- srcSpanFile,
- srcSpanStartLine, srcSpanEndLine,
- srcSpanStartCol, srcSpanEndCol,
srcSpanStart, srcSpanEnd,
+ optSrcSpanFileName,
+
+ -- These are dubious exports, because they crash on some inputs,
+ -- used only in Lexer.x where we are sure what the Span looks like
+ srcSpanFile,
+ srcSpanStartLine, srcSpanEndLine,
+ srcSpanStartCol, srcSpanEndCol,
Located(..), getLoc, unLoc, noLoc, eqLocated, cmpLocated, combineLocs, addCLoc
) where
#include "HsVersions.h"
-import Util ( thenCmp )
+import Util
import Outputable
import FastString
\end{code}
-- Don't ask me why lines start at 1 and columns start at
-- zero. That's just the way it is, so there. --SDM
- | ImportedLoc String -- Module name
+ | ImportedLoc FastString -- Module name
| UnhelpfulLoc FastString -- Just a general indication
\end{code}
mkSrcLoc x line col = SrcLoc x line col
noSrcLoc = UnhelpfulLoc FSLIT("<no location info>")
generatedSrcLoc = UnhelpfulLoc FSLIT("<compiler-generated code>")
-wiredInSrcLoc = UnhelpfulLoc FSLIT("<wired into compiler>")
interactiveSrcLoc = UnhelpfulLoc FSLIT("<interactive session>")
mkGeneralSrcLoc :: FastString -> SrcLoc
mkGeneralSrcLoc = UnhelpfulLoc
-importedSrcLoc :: String -> SrcLoc
+importedSrcLoc :: FastString -> SrcLoc
importedSrcLoc mod_name = ImportedLoc mod_name
isGoodSrcLoc (SrcLoc _ _ _) = True
cmpSrcLoc (ImportedLoc _) other = LT
cmpSrcLoc (SrcLoc s1 l1 c1) (SrcLoc s2 l2 c2)
- = (s1 `compare` s2) `thenCmp` (l1 `cmpline` l2) `thenCmp` (c1 `cmpline` c2)
- where
- l1 `cmpline` l2 | l1 < l2 = LT
- | l1 == l2 = EQ
- | otherwise = GT
+ = (s1 `compare` s2) `thenCmp` (l1 `compare` l2) `thenCmp` (c1 `compare` c2)
cmpSrcLoc (SrcLoc _ _ _) other = GT
instance Outputable SrcLoc where
hcat [text "{-# LINE ", int src_line, space,
char '\"', ftext src_path, text " #-}"]
- ppr (ImportedLoc mod) = ptext SLIT("Imported from") <+> text mod
+ ppr (ImportedLoc mod) = ptext SLIT("Defined in") <+> ftext mod
ppr (UnhelpfulLoc s) = ftext s
\end{code}
srcSpanCol :: !Int
}
- | ImportedSpan String -- Module name
+ | ImportedSpan FastString -- Module name
| UnhelpfulSpan FastString -- Just a general indication
-- also used to indicate an empty span
(srcSpanStart a `compare` srcSpanStart b) `thenCmp`
(srcSpanEnd a `compare` srcSpanEnd b)
-noSrcSpan = UnhelpfulSpan FSLIT("<no location info>")
+noSrcSpan = UnhelpfulSpan FSLIT("<no location info>")
+wiredInSrcSpan = UnhelpfulSpan FSLIT("<wired into compiler>")
+importedSrcSpan = ImportedSpan
mkGeneralSrcSpan :: FastString -> SrcSpan
mkGeneralSrcSpan = UnhelpfulSpan
isGoodSrcSpan SrcSpanPoint{} = True
isGoodSrcSpan _ = False
+optSrcSpanFileName :: SrcSpan -> Maybe FastString
+optSrcSpanFileName (SrcSpanOneLine { srcSpanFile = nm }) = Just nm
+optSrcSpanFileName (SrcSpanMultiLine { srcSpanFile = nm }) = Just nm
+optSrcSpanFileName (SrcSpanPoint { srcSpanFile = nm}) = Just nm
+optSrcSpanFileName _ = Nothing
+
+isOneLineSpan :: SrcSpan -> Bool
+-- True if the span is known to straddle more than one line
+-- By default, it returns False
+isOneLineSpan s
+ | isGoodSrcSpan s = srcSpanStartLine s == srcSpanEndLine s
+ | otherwise = False
+
+--------------------------------------------------------
+-- Don't export these four;
+-- they panic on Imported, Unhelpful.
+-- They are for internal use only
+-- Urk! Some are needed for Lexer.x; see comment in export list
+
srcSpanStartLine SrcSpanOneLine{ srcSpanLine=l } = l
srcSpanStartLine SrcSpanMultiLine{ srcSpanSLine=l } = l
srcSpanStartLine SrcSpanPoint{ srcSpanLine=l } = l
srcSpanEndCol SrcSpanMultiLine{ srcSpanECol=c } = c
srcSpanEndCol SrcSpanPoint{ srcSpanCol=c } = c
srcSpanEndCol _ = panic "SrcLoc.srcSpanEndCol"
+--------------------------------------------------------
srcSpanStart (ImportedSpan str) = ImportedLoc str
srcSpanStart (UnhelpfulSpan str) = UnhelpfulLoc str
-srcSpanStart s =
- mkSrcLoc (srcSpanFile s)
- (srcSpanStartLine s)
- (srcSpanStartCol s)
+srcSpanStart s = mkSrcLoc (srcSpanFile s)
+ (srcSpanStartLine s)
+ (srcSpanStartCol s)
srcSpanEnd (ImportedSpan str) = ImportedLoc str
srcSpanEnd (UnhelpfulSpan str) = UnhelpfulLoc str
col2 = srcSpanEndCol end
file = srcSpanFile start
-pprDefnLoc :: SrcLoc -> SDoc
+pprDefnLoc :: SrcSpan -> SDoc
-- "defined at ..." or "imported from ..."
pprDefnLoc loc
- | isGoodSrcLoc loc = ptext SLIT("Defined at") <+> ppr loc
- | otherwise = ppr loc
+ | isGoodSrcSpan loc = ptext SLIT("Defined at") <+> ppr loc
+ | otherwise = ppr loc
instance Outputable SrcSpan where
ppr span
char ':', int col
]
-pprUserSpan (ImportedSpan mod) = ptext SLIT("Imported from") <+> quotes (text mod)
+pprUserSpan (ImportedSpan mod) = ptext SLIT("Defined in") <+> ftext mod
pprUserSpan (UnhelpfulSpan s) = ftext s
\end{code}