[project @ 2002-09-13 15:02:25 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / SrcLoc.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 %************************************************************************
5 %*                                                                      *
6 \section[SrcLoc]{The @SrcLoc@ type}
7 %*                                                                      *
8 %************************************************************************
9
10 \begin{code}
11 module SrcLoc (
12         SrcLoc,                 -- Abstract
13
14         mkSrcLoc, isGoodSrcLoc, isWiredInLoc,
15         noSrcLoc,               -- "I'm sorry, I haven't a clue"
16
17         importedSrcLoc,         -- Unknown place in an interface
18         wiredInSrcLoc,          -- Something wired into the compiler
19         generatedSrcLoc,        -- Code generated within the compiler
20
21         incSrcLine, replaceSrcLine,
22         
23         srcLocFile,             -- return the file name part.
24         srcLocLine              -- return the line part.
25     ) where
26
27 #include "HsVersions.h"
28
29 import Util             ( thenCmp )
30 import Outputable
31 import FastString       ( unpackFS )
32 import FastTypes
33 import FastString
34
35 import GLAEXTS          ( (+#) )
36 \end{code}
37
38 %************************************************************************
39 %*                                                                      *
40 \subsection[SrcLoc-SrcLocations]{Source-location information}
41 %*                                                                      *
42 %************************************************************************
43
44 We keep information about the {\em definition} point for each entity;
45 this is the obvious stuff:
46 \begin{code}
47 data SrcLoc
48   = WiredInLoc          -- Used exclusively for Ids and TyCons
49                         -- that are totally wired in to the
50                         -- compiler.  That supports the 
51                         -- occasionally-useful predicate
52                         -- isWiredInName
53
54   | SrcLoc      FastString      -- A precise location (file name)
55                 FastInt
56
57   | UnhelpfulSrcLoc FastString  -- Just a general indication
58 \end{code}
59
60 Note that an entity might be imported via more than one route, and
61 there could be more than one ``definition point'' --- in two or more
62 \tr{.hi} files.  We deemed it probably-unworthwhile to cater for this
63 rare case.
64
65 %************************************************************************
66 %*                                                                      *
67 \subsection[SrcLoc-access-fns]{Access functions for names}
68 %*                                                                      *
69 %************************************************************************
70
71 Things to make 'em:
72 \begin{code}
73 mkSrcLoc x y      = SrcLoc x (iUnbox y)
74 wiredInSrcLoc     = WiredInLoc
75 noSrcLoc          = UnhelpfulSrcLoc FSLIT("<No locn>")
76 importedSrcLoc    = UnhelpfulSrcLoc FSLIT("<imported>")
77 generatedSrcLoc   = UnhelpfulSrcLoc FSLIT("<compiler-generated-code>")
78
79 isGoodSrcLoc (SrcLoc _ _) = True
80 isGoodSrcLoc other        = False
81
82 isWiredInLoc WiredInLoc = True
83 isWiredInLoc other      = False
84
85 srcLocFile :: SrcLoc -> FastString
86 srcLocFile (SrcLoc fname _) = fname
87
88 srcLocLine :: SrcLoc -> FastInt
89 srcLocLine (SrcLoc _ l) = l
90
91 incSrcLine :: SrcLoc -> SrcLoc
92 incSrcLine (SrcLoc s l) = SrcLoc s (l +# 1#)
93 incSrcLine loc          = loc
94
95 replaceSrcLine :: SrcLoc -> FastInt -> SrcLoc
96 replaceSrcLine (SrcLoc s _) l = SrcLoc s l
97 \end{code}
98
99 %************************************************************************
100 %*                                                                      *
101 \subsection[SrcLoc-instances]{Instance declarations for various names}
102 %*                                                                      *
103 %************************************************************************
104
105 \begin{code}
106 -- SrcLoc is an instance of Ord so that we can sort error messages easily
107 instance Eq SrcLoc where
108   loc1 == loc2 = case loc1 `cmpSrcLoc` loc2 of
109                    EQ    -> True
110                    other -> False
111
112 instance Ord SrcLoc where
113   compare = cmpSrcLoc
114
115 cmpSrcLoc WiredInLoc WiredInLoc = EQ
116 cmpSrcLoc WiredInLoc other      = LT
117
118 cmpSrcLoc (UnhelpfulSrcLoc s1) (UnhelpfulSrcLoc s2) = s1 `compare` s2
119 cmpSrcLoc (UnhelpfulSrcLoc s1) other                = GT
120
121 cmpSrcLoc (SrcLoc s1 l1) WiredInLoc          = GT
122 cmpSrcLoc (SrcLoc s1 l1) (UnhelpfulSrcLoc _) = LT
123 cmpSrcLoc (SrcLoc s1 l1) (SrcLoc s2 l2)      = (s1 `compare` s2) `thenCmp` (l1 `cmpline` l2)
124                                              where
125                                                 l1 `cmpline` l2 | l1 <#  l2 = LT
126                                                                 | l1 ==# l2 = EQ
127                                                                 | otherwise = GT 
128                                           
129 instance Outputable SrcLoc where
130     ppr (SrcLoc src_path src_line)
131       = getPprStyle $ \ sty ->
132         if userStyle sty || debugStyle sty then
133            hcat [ ftext src_path, char ':', int (iBox src_line) ]
134         else
135            hcat [text "{-# LINE ", int (iBox src_line), space,
136                  char '\"', ftext src_path, text " #-}"]
137       where
138         src_file = unpackFS src_path    -- Leave the directory prefix intact,
139                                         -- so emacs can find the file
140
141     ppr (UnhelpfulSrcLoc s) = ftext s
142     ppr WiredInLoc          = ptext SLIT("<Wired in>")
143 \end{code}