Improve printing of Orig RdrNames
authorsimonpj@microsoft.com <unknown>
Thu, 28 May 2009 16:52:15 +0000 (16:52 +0000)
committersimonpj@microsoft.com <unknown>
Thu, 28 May 2009 16:52:15 +0000 (16:52 +0000)
In Tempate Haskell -ddump-splices, the "after" expression is populated
with RdrNames, many of which are Orig things.  We used to print these
fully-qualified, but that's a bit heavy.

This patch refactors the code a bit so that the same print-unqualified
mechanism we use for Names also works for RdrNames.  Lots of comments
too, because it took me a while to figure out how it all worked again.

compiler/basicTypes/Name.lhs
compiler/basicTypes/RdrName.lhs
compiler/main/HscTypes.lhs
compiler/utils/Outputable.lhs

index cba20f5..9f23f96 100644 (file)
@@ -63,7 +63,7 @@ module Name (
        NamedThing(..),
        getSrcLoc, getSrcSpan, getOccString,
 
-       pprInfixName, pprPrefixName,
+       pprInfixName, pprPrefixName, pprModulePrefix,
 
        -- Re-export the OccName stuff
        module OccName
@@ -396,23 +396,16 @@ pprName (Name {n_sort = sort, n_uniq = u, n_occ = occ})
 
 pprExternal :: PprStyle -> Unique -> Module -> OccName -> Bool -> BuiltInSyntax -> SDoc
 pprExternal sty uniq mod occ is_wired is_builtin
-  | codeStyle sty        = ppr mod <> char '_' <> ppr_z_occ_name occ
+  | codeStyle sty = ppr mod <> char '_' <> ppr_z_occ_name occ
        -- In code style, always qualify
        -- ToDo: maybe we could print all wired-in things unqualified
        --       in code style, to reduce symbol table bloat?
- | debugStyle sty       = ppr mod <> dot <> ppr_occ_name occ
-               <> braces (hsep [if is_wired then ptext (sLit "(w)") else empty,
-                                pprNameSpaceBrief (occNameSpace occ), 
-                                pprUnique uniq])
-  | BuiltInSyntax <- is_builtin  = ppr_occ_name occ
-       -- never qualify builtin syntax
-  | NameQual modname <- qual_name = ppr modname <> dot <> ppr_occ_name occ
-        -- see HscTypes.mkPrintUnqualified and Outputable.QualifyName:
-  | NameNotInScope1 <- qual_name  = ppr mod <> dot <> ppr_occ_name occ
-  | NameNotInScope2 <- qual_name  = ppr (modulePackageId mod) <> char ':' <>
-                                    ppr (moduleName mod) <> dot <> ppr_occ_name occ
-  | otherwise                    = ppr_occ_name occ
-  where qual_name = qualName sty mod occ
+  | debugStyle sty = ppr mod <> dot <> ppr_occ_name occ
+                    <> braces (hsep [if is_wired then ptext (sLit "(w)") else empty,
+                                     pprNameSpaceBrief (occNameSpace occ), 
+                                     pprUnique uniq])
+  | BuiltInSyntax <- is_builtin = ppr_occ_name occ  -- Never qualify builtin syntax
+  | otherwise                  = pprModulePrefix sty mod occ <> ppr_occ_name occ
 
 pprInternal :: PprStyle -> Unique -> OccName -> SDoc
 pprInternal sty uniq occ
@@ -435,6 +428,18 @@ pprSystem sty uniq occ
                                -- is unlikely to be informative (like 's'),
                                -- so print the unique
 
+
+pprModulePrefix :: PprStyle -> Module -> OccName -> SDoc
+-- Print the "M." part of a name, based on whether it's in scope or not
+-- See Note [Printing original names] in HscTypes
+pprModulePrefix sty mod occ
+  = case qualName sty mod occ of                  -- See Outputable.QualifyName:
+      NameQual modname -> ppr modname <> dot       -- Name is in scope       
+      NameNotInScope1  -> ppr mod <> dot           -- Not in scope
+      NameNotInScope2  -> ppr (modulePackageId mod) <> colon     -- Module not in
+                          <> ppr (moduleName mod) <> dot         -- scope eithber
+      _otherwise       -> empty
+
 ppr_underscore_unique :: Unique -> SDoc
 -- Print an underscore separating the name from its unique
 -- But suppress it if we aren't printing the uniques anyway
index 31ffe6a..89e1fdc 100644 (file)
@@ -251,7 +251,7 @@ instance Outputable RdrName where
     ppr (Exact name)   = ppr name
     ppr (Unqual occ)   = ppr occ
     ppr (Qual mod occ) = ppr mod <> dot <> ppr occ
-    ppr (Orig mod occ) = ppr mod <> dot <> ppr occ
+    ppr (Orig mod occ) = getPprStyle (\sty -> pprModulePrefix sty mod occ <> ppr occ)
 
 instance OutputableBndr RdrName where
     pprBndr _ n 
index c1e6f34..f23ff58 100644 (file)
@@ -54,8 +54,9 @@ module HscTypes (
 
         -- * Interactive context
        InteractiveContext(..), emptyInteractiveContext, 
-       icPrintUnqual, mkPrintUnqualified, extendInteractiveContext,
+       icPrintUnqual, extendInteractiveContext,
         substInteractiveContext,
+        mkPrintUnqualified, pprModulePrefix,
 
        -- * Interfaces
        ModIface(..), mkIfaceWarnCache, mkIfaceHashCache, mkIfaceFixCache,
@@ -1202,6 +1203,8 @@ substInteractiveContext ictxt@InteractiveContext{ic_tmp_ids=ids} subst =
 %*                                                                     *
 %************************************************************************
 
+Note [Printing original names]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Deciding how to print names is pretty tricky.  We are given a name
 P:M.T, where P is the package name, M is the defining module, and T is
 the occurrence name, and we have to decide in which form to display
@@ -1211,19 +1214,24 @@ Ideally we want to display the name in the form in which it is in
 scope.  However, the name might not be in scope at all, and that's
 where it gets tricky.  Here are the cases:
 
- 1. T   uniquely maps to  P:M.T                         --->  "T"
- 2. there is an X for which X.T uniquely maps to  P:M.T --->  "X.T"
- 3. there is no binding for "M.T"                       --->  "M.T"
- 4. otherwise                                           --->  "P:M.T"
-
-3 and 4 apply when P:M.T is not in scope.  In these cases we want to
-refer to the name as "M.T", but "M.T" might mean something else in the
-current scope (e.g. if there's an "import X as M"), so to avoid
-confusion we avoid using "M.T" if there's already a binding for it.
-
-There's one further subtlety: if the module M cannot be imported
-because it is not exposed by any package, then we must refer to it as
-"P:M".  This is handled by the qual_mod component of PrintUnqualified.
+ 1. T uniquely maps to  P:M.T      --->  "T"      NameUnqual
+ 2. There is an X for which X.T 
+       uniquely maps to  P:M.T     --->  "X.T"    NameQual X
+ 3. There is no binding for "M.T"  --->  "M.T"    NameNotInScope1
+ 4. Otherwise                      --->  "P:M.T"  NameNotInScope2
+
+(3) and (4) apply when the entity P:M.T is not in the GlobalRdrEnv at
+all. In these cases we still want to refer to the name as "M.T", *but*
+"M.T" might mean something else in the current scope (e.g. if there's
+an "import X as M"), so to avoid confusion we avoid using "M.T" if
+there's already a binding for it.  Instead we write P:M.T.
+
+There's one further subtlety: in case (3), what if there are two
+things around, P1:M.T and P2:M.T?  Then we don't want to print both of
+them as M.T!  However only one of the modules P1:M and P2:M can be
+exposed (say P2), so we use M.T for that, and P1:M.T for the other one.
+This is handled by the qual_mod component of PrintUnqualified, inside
+the (ppr mod) of case (3), in Name.pprModulePrefix
 
 \begin{code}
 -- | Creates some functions that work out the best ways to format
index 023d7d0..ed47609 100644 (file)
@@ -129,6 +129,7 @@ data Depth = AllTheWay
 -- in source code, names are qualified by ModuleNames.
 type QueryQualifyName = Module -> OccName -> QualifyName
 
+-- See Note [Printing original names] in HscTypes
 data QualifyName                        -- given P:M.T
         = NameUnqual                    -- refer to it as "T"
         | NameQual ModuleName           -- refer to it as "X.T" for the supplied X