Make PrettyPrintEnv only contain named things

This commit is contained in:
Mitchell Rosen 2021-11-08 17:28:46 -05:00
parent d9f3dc923e
commit 070db99afd
5 changed files with 29 additions and 18 deletions

View File

@ -14,6 +14,7 @@ where
import Unison.Prelude
import Unison.HashQualified ( HashQualified )
import qualified Unison.HashQualified' as HQ'
import Unison.Name ( Name )
import Unison.Reference ( Reference )
import Unison.Referent ( Referent )
@ -23,11 +24,11 @@ import qualified Unison.ConstructorType as CT
data PrettyPrintEnv = PrettyPrintEnv {
-- names for terms, constructors, and requests
terms :: Referent -> Maybe (HashQualified Name),
terms :: Referent -> Maybe (HQ'.HashQualified Name),
-- names for types
types :: Reference -> Maybe (HashQualified Name) }
types :: Reference -> Maybe (HQ'.HashQualified Name) }
patterns :: PrettyPrintEnv -> Reference -> Int -> Maybe (HashQualified Name)
patterns :: PrettyPrintEnv -> Reference -> Int -> Maybe (HQ'.HashQualified Name)
patterns ppe r cid = terms ppe (Referent.Con r cid CT.Data)
<|>terms ppe (Referent.Con r cid CT.Effect)
@ -46,16 +47,20 @@ todoHashLength = 10
termName :: PrettyPrintEnv -> Referent -> HashQualified Name
termName env r =
fromMaybe (HQ.take todoHashLength $ HQ.fromReferent r) (terms env r)
case terms env r of
Nothing -> HQ.take todoHashLength (HQ.fromReferent r)
Just name -> HQ'.toHQ name
typeName :: PrettyPrintEnv -> Reference -> HashQualified Name
typeName env r =
fromMaybe (HQ.take todoHashLength $ HQ.fromReference r) (types env r)
case types env r of
Nothing -> HQ.take todoHashLength (HQ.fromReference r)
Just name -> HQ'.toHQ name
patternName :: PrettyPrintEnv -> Reference -> Int -> HashQualified Name
patternName env r cid =
case patterns env r cid of
Just name -> name
Just name -> HQ'.toHQ name
Nothing -> HQ.take todoHashLength $ HQ.fromPattern r cid
instance Monoid PrettyPrintEnv where

View File

@ -5,7 +5,7 @@ module Unison.PrettyPrintEnv.Names (fromNames, fromSuffixNames) where
import Unison.Prelude
import qualified Data.Set as Set
import qualified Unison.HashQualified as HQ
import qualified Unison.HashQualified' as HQ'
import qualified Unison.Name as Name
import Unison.NamesWithHistory (NamesWithHistory)
import qualified Unison.NamesWithHistory as Names
@ -14,9 +14,9 @@ import Unison.Util.List (safeHead)
fromNames :: Int -> NamesWithHistory -> PrettyPrintEnv
fromNames len names = PrettyPrintEnv terms' types' where
terms' r = shortestName . Set.map Name.convert $ Names.termName len r names
types' r = shortestName . Set.map Name.convert $ Names.typeName len r names
shortestName ns = safeHead $ HQ.sortByLength (toList ns)
terms' r = shortestName (Names.termName len r names)
types' r = shortestName (Names.typeName len r names)
shortestName ns = safeHead $ HQ'.sortByLength (toList ns)
fromSuffixNames :: Int -> NamesWithHistory -> PrettyPrintEnv
fromSuffixNames len names = PrettyPrintEnv terms' types' where

View File

@ -118,6 +118,13 @@ requalify hq r = case hq of
NameOnly n -> fromNamedReferent n r
HashQualified n _ -> fromNamedReferent n r
-- | Sort the list of names by length of segments: smaller number of segments is listed first. NameOnly < HashQualified
sortByLength :: [HashQualified Name] -> [HashQualified Name]
sortByLength =
sortOn \case
NameOnly name -> (length (Name.reverseSegments name), Nothing, Name.isAbsolute name)
HashQualified name hash -> (length (Name.reverseSegments name), Just hash, Name.isAbsolute name)
-- `HashQualified` is usually used for display, so we sort it alphabetically
instance Name.Alphabetical n => Ord (HashQualified n) where
compare (NameOnly n) (NameOnly n2) = Name.compareAlphabetical n n2

View File

@ -49,10 +49,9 @@ toName = \case
-- [.foo.bar, foo.bar] -> [foo.bar, .foo.bar]
sortByLength :: [HashQualified Name] -> [HashQualified Name]
sortByLength hs = sortOn f hs where
f (NameOnly n) = (countDots n, 0, Left n)
f (HashQualified n _h) = (countDots n, 1, Left n)
f (NameOnly n) = (length (Name.reverseSegments n), 0, Left n)
f (HashQualified n _h) = (length (Name.reverseSegments n), 1, Left n)
f (HashOnly h) = (maxBound, 0, Right h)
countDots n = Text.count "." (Text.dropEnd 1 (Name.toText n))
hasName, hasHash :: HashQualified Name -> Bool
hasName = isJust . toName

View File

@ -231,8 +231,8 @@ termName length r NamesWithHistory{..} =
where hq n = HQ'.take length (HQ'.fromNamedReferent n r)
isConflicted n = R.manyDom n (Names.terms currentNames)
suffixedTypeName :: Int -> Reference -> NamesWithHistory -> [HQ.HashQualified Name]
suffixedTermName :: Int -> Referent -> NamesWithHistory -> [HQ.HashQualified Name]
suffixedTypeName :: Int -> Reference -> NamesWithHistory -> [HQ'.HashQualified Name]
suffixedTermName :: Int -> Referent -> NamesWithHistory -> [HQ'.HashQualified Name]
(suffixedTermName,suffixedTypeName) =
( suffixedName termName (Names.terms . currentNames) HQ'.fromNamedReferent
, suffixedName typeName (Names.types . currentNames) HQ'.fromNamedReference )
@ -240,19 +240,19 @@ suffixedTermName :: Int -> Referent -> NamesWithHistory -> [HQ.HashQualified Nam
suffixedName fallback getRel hq' length r ns@(getRel -> rel) =
if R.memberRan r rel
then go $ toList (R.lookupRan r rel)
else sort $ map Name.convert $ Set.toList (fallback length r ns)
else sort $ Set.toList (fallback length r ns)
where
-- Orders names, using these criteria, in this order:
-- 1. NameOnly comes before HashQualified,
-- 2. Shorter names (in terms of segment count) come before longer ones
-- 3. If same on attributes 1 and 2, compare alphabetically
go :: [Name] -> [HashQualified Name]
go :: [Name] -> [HQ'.HashQualified Name]
go fqns = map (view _4) . sort $ map f fqns where
f fqn = let
n' = Name.shortestUniqueSuffix fqn r rel
isHQ'd = R.manyDom fqn rel -- it is conflicted
hq n = HQ'.take length (hq' n r)
hqn = Name.convert $ if isHQ'd then hq n' else HQ'.fromName n'
hqn = if isHQ'd then hq n' else HQ'.fromName n'
in (isHQ'd, Name.countSegments fqn, Name.isAbsolute n', hqn)
-- Set HashQualified -> Branch m -> Action' m v Names