Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/refactor: add merge api #5259

Merged
merged 25 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2860665
extract findConflictedAlias to Unison.Merge
mitchellwrosen Aug 1, 2024
2e328d2
remove "old style" merge functions that take merge database as argument
mitchellwrosen Aug 1, 2024
1c0d1a1
delete MergeDatabase
mitchellwrosen Aug 1, 2024
acc63bf
generalize findConflictedAlias a bit
mitchellwrosen Aug 1, 2024
e89b0ae
⅄ 24-07-31-merge-refactor → 24-08-01-merge-api
mitchellwrosen Aug 1, 2024
8041e25
tease apart identifyDependents
mitchellwrosen Aug 1, 2024
5bf55a4
Merge branch '24-07-31-merge-refactor' into 24-08-01-merge-api
mitchellwrosen Aug 1, 2024
3f73d7f
automatically run ormolu
mitchellwrosen Aug 1, 2024
b946980
⅄ trunk → 24-08-01-merge-api
mitchellwrosen Aug 5, 2024
325e4ee
separate partitioning from asserting no builtins
mitchellwrosen Aug 5, 2024
565eb66
don't hydrate twice, and hyrate lca defns too
mitchellwrosen Aug 5, 2024
2ffbba4
automatically run ormolu
mitchellwrosen Aug 5, 2024
4acee45
extract PPE making to merge API
mitchellwrosen Aug 5, 2024
816d785
extract rendering conflicts and dependents to a helper
mitchellwrosen Aug 5, 2024
aedb9c2
begin moving over to "mergeblob" api
mitchellwrosen Aug 5, 2024
d5a9585
continue refactoring
mitchellwrosen Aug 6, 2024
c88c4a3
rename a couple things
mitchellwrosen Aug 6, 2024
53209c3
more mergeblob work
mitchellwrosen Aug 8, 2024
3b37c4b
move some of the mergeblob API over to unison-merge
mitchellwrosen Aug 8, 2024
2b33116
automatically run ormolu
mitchellwrosen Aug 8, 2024
a40bfd6
move the rest of the mergeblobs over
mitchellwrosen Aug 8, 2024
c230be2
move more code around
mitchellwrosen Aug 8, 2024
0d560d2
delete unused import
mitchellwrosen Aug 8, 2024
1741ffb
⅄ trunk → 24-08-01-merge-api
mitchellwrosen Aug 8, 2024
ed555a3
Merge branch 'trunk' into 24-08-01-merge-api
aryairani Aug 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion codebase2/core/Unison/NameSegment.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Unison.NameSegment
( NameSegment,
toUnescapedText,

-- * Sentinel name segments
defaultPatchSegment,
Expand All @@ -23,7 +24,7 @@ module Unison.NameSegment
)
where

import Unison.NameSegment.Internal (NameSegment (NameSegment))
import Unison.NameSegment.Internal (NameSegment (NameSegment, toUnescapedText))

------------------------------------------------------------------------------------------------------------------------
-- special segment names
Expand Down
1 change: 1 addition & 0 deletions lib/unison-util-relation/src/Unison/Util/BiMultimap.hs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ withoutRan ys m =
domain :: BiMultimap a b -> Map a (NESet b)
domain = toMultimap

-- | /O(1)/.
range :: BiMultimap a b -> Map b a
range = toMapR

Expand Down
17 changes: 8 additions & 9 deletions parser-typechecker/src/Unison/Codebase/Type.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ module Unison.Codebase.Type
where

import U.Codebase.HashTags (CausalHash)
import U.Codebase.Reference qualified as V2
import Unison.Codebase.Branch (Branch)
import Unison.CodebasePath (CodebasePath)
import Unison.ConstructorType qualified as CT
import Unison.DataDeclaration (Decl)
import Unison.Hash (Hash)
import Unison.Prelude
import Unison.Reference (Reference, TypeReference)
import Unison.Reference (Reference, TypeReference, TermReferenceId, TypeReferenceId)
import Unison.Reference qualified as Reference
import Unison.Referent qualified as Referent
import Unison.ShortHash (ShortHash)
Expand All @@ -31,27 +30,27 @@ data Codebase m v a = Codebase
--
-- Note that it is possible to call 'putTerm', then 'getTerm', and receive @Nothing@, per the semantics of
-- 'putTerm'.
getTerm :: Reference.Id -> Sqlite.Transaction (Maybe (Term v a)),
getTerm :: TermReferenceId -> Sqlite.Transaction (Maybe (Term v a)),
-- | Get the type of a user-defined term.
--
-- Note that it is possible to call 'putTerm', then 'getTypeOfTermImpl', and receive @Nothing@, per the semantics of
-- 'putTerm'.
getTypeOfTermImpl :: Reference.Id -> Sqlite.Transaction (Maybe (Type v a)),
getTypeOfTermImpl :: TermReferenceId -> Sqlite.Transaction (Maybe (Type v a)),
-- | Get a type declaration.
--
-- Note that it is possible to call 'putTypeDeclaration', then 'getTypeDeclaration', and receive @Nothing@, per the
-- semantics of 'putTypeDeclaration'.
getTypeDeclaration :: Reference.Id -> Sqlite.Transaction (Maybe (Decl v a)),
getTypeDeclaration :: TypeReferenceId -> Sqlite.Transaction (Maybe (Decl v a)),
-- | Get the type of a given decl.
getDeclType :: V2.Reference -> Sqlite.Transaction CT.ConstructorType,
getDeclType :: TypeReference -> Sqlite.Transaction CT.ConstructorType,
-- | Enqueue the put of a user-defined term (with its type) into the codebase, if it doesn't already exist. The
-- implementation may choose to delay the put until all of the term's (and its type's) references are stored as
-- well.
putTerm :: Reference.Id -> Term v a -> Type v a -> Sqlite.Transaction (),
putTerm :: TermReferenceId -> Term v a -> Type v a -> Sqlite.Transaction (),
putTermComponent :: Hash -> [(Term v a, Type v a)] -> Sqlite.Transaction (),
-- | Enqueue the put of a type declaration into the codebase, if it doesn't already exist. The implementation may
-- choose to delay the put until all of the type declaration's references are stored as well.
putTypeDeclaration :: Reference.Id -> Decl v a -> Sqlite.Transaction (),
putTypeDeclaration :: TypeReferenceId -> Decl v a -> Sqlite.Transaction (),
putTypeDeclarationComponent :: Hash -> [Decl v a] -> Sqlite.Transaction (),
-- getTermComponent :: Hash -> m (Maybe [Term v a]),
getTermComponentWithTypes :: Hash -> Sqlite.Transaction (Maybe [(Term v a, Type v a)]),
Expand All @@ -66,7 +65,7 @@ data Codebase m v a = Codebase
-- | Copy a branch and all of its dependencies from this codebase into the given codebase.
syncToDirectory :: CodebasePath -> Branch m -> m (),
-- | @getWatch k r@ returns watch result @t@ that was previously put by @putWatch k r t@.
getWatch :: WK.WatchKind -> Reference.Id -> Sqlite.Transaction (Maybe (Term v a)),
getWatch :: WK.WatchKind -> TermReferenceId -> Sqlite.Transaction (Maybe (Term v a)),
-- | Get the set of user-defined terms-or-constructors that have the given type.
termsOfTypeImpl :: Reference -> Sqlite.Transaction (Set Referent.Id),
-- | Get the set of user-defined terms-or-constructors mention the given type anywhere in their signature.
Expand Down
97 changes: 97 additions & 0 deletions parser-typechecker/src/Unison/Syntax/FilePrinter.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
module Unison.Syntax.FilePrinter
( renderDefnsForUnisonFile,
)
where

import Control.Lens (mapped, _1)
import Control.Monad.Writer (Writer)
import Control.Monad.Writer qualified as Writer
import Data.List qualified as List
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Unison.Builtin.Decls qualified as Builtin.Decls
import Unison.ConstructorReference (ConstructorReference, GConstructorReference (..))
import Unison.DataDeclaration (Decl)
import Unison.DeclNameLookup (DeclNameLookup, expectConstructorNames)
import Unison.HashQualified qualified as HQ
import Unison.HashQualifiedPrime qualified as HQ'
import Unison.Name (Name)
import Unison.Prelude
import Unison.PrettyPrintEnvDecl (PrettyPrintEnvDecl (..))
import Unison.Reference (TypeReferenceId)
import Unison.Reference qualified as Reference
import Unison.Referent (Referent)
import Unison.Referent qualified as Referent
import Unison.Syntax.DeclPrinter (AccessorName)
import Unison.Syntax.DeclPrinter qualified as DeclPrinter
import Unison.Syntax.TermPrinter qualified as TermPrinter
import Unison.Term (Term)
import Unison.Type (Type)
import Unison.Typechecker qualified as Typechecker
import Unison.Util.Defns (Defns (..), DefnsF)
import Unison.Util.Pretty (ColorText, Pretty)
import Unison.Util.Pretty qualified as Pretty
import Unison.Var (Var)

-- | Render definitions destined for a Unison file.
--
-- This first renders the types (discovering which record accessors will be generated upon parsing), then renders the
-- terms (being careful not to render any record accessors, since those would cause duplicate binding errors upon
-- parsing).
renderDefnsForUnisonFile ::
forall a v.
(Var v, Monoid a) =>
DeclNameLookup ->
PrettyPrintEnvDecl ->
DefnsF (Map Name) (Term v a, Type v a) (TypeReferenceId, Decl v a) ->
DefnsF (Map Name) (Pretty ColorText) (Pretty ColorText)
renderDefnsForUnisonFile declNameLookup ppe defns =
let (types, accessorNames) = Writer.runWriter (Map.traverseWithKey renderType defns.types)
in Defns
{ terms = Map.mapMaybeWithKey (renderTerm accessorNames) defns.terms,
types
}
where
renderType :: Name -> (TypeReferenceId, Decl v a) -> Writer (Set AccessorName) (Pretty ColorText)
renderType name (ref, typ) =
fmap Pretty.syntaxToColor $
DeclPrinter.prettyDeclW
-- Sort of a hack; since the decl printer looks in the PPE for names of constructors,
-- we just delete all term names out and add back the constructors...
-- probably no need to wipe out the suffixified side but we do it anyway
(setPpedToConstructorNames declNameLookup name ref ppe)
(Reference.fromId ref)
(HQ.NameOnly name)
typ

renderTerm :: Set Name -> Name -> (Term v a, Type v a) -> Maybe (Pretty ColorText)
renderTerm accessorNames name (term, typ) = do
guard (not (Set.member name accessorNames))
let hqName = HQ.NameOnly name
let rendered
| Typechecker.isEqual (Builtin.Decls.testResultListType mempty) typ =
"test> " <> TermPrinter.prettyBindingWithoutTypeSignature ppe.suffixifiedPPE hqName term
| otherwise = TermPrinter.prettyBinding ppe.suffixifiedPPE hqName term
Just (Pretty.syntaxToColor rendered)

setPpedToConstructorNames :: DeclNameLookup -> Name -> TypeReferenceId -> PrettyPrintEnvDecl -> PrettyPrintEnvDecl
setPpedToConstructorNames declNameLookup name ref =
set (#unsuffixifiedPPE . #termNames) referentNames
. set (#suffixifiedPPE . #termNames) referentNames
where
constructorNameMap :: Map ConstructorReference Name
constructorNameMap =
Map.fromList
( name
& expectConstructorNames declNameLookup
& List.zip [0 ..]
& over (mapped . _1) (ConstructorReference (Reference.fromId ref))
)

referentNames :: Referent -> [(HQ'.HashQualified Name, HQ'.HashQualified Name)]
referentNames = \case
Referent.Con conRef _ ->
case Map.lookup conRef constructorNameMap of
Nothing -> []
Just conName -> let hqConName = HQ'.NameOnly conName in [(hqConName, hqConName)]
Referent.Ref _ -> []
1 change: 1 addition & 0 deletions parser-typechecker/unison-parser-typechecker.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ library
Unison.Syntax.DeclParser
Unison.Syntax.DeclPrinter
Unison.Syntax.FileParser
Unison.Syntax.FilePrinter
Unison.Syntax.NamePrinter
Unison.Syntax.TermParser
Unison.Syntax.TermPrinter
Expand Down
8 changes: 8 additions & 0 deletions unison-cli/src/Unison/Cli/Monad.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module Unison.Cli.Monad
-- * Running transactions
runTransaction,
runTransactionWithRollback,
runTransactionWithRollback2,

-- * Internal
setMostRecentProjectPath,
Expand Down Expand Up @@ -444,3 +445,10 @@ runTransactionWithRollback action = do
Env {codebase} <- ask
liftIO (Codebase.runTransactionWithRollback codebase \rollback -> Right <$> action (\output -> rollback (Left output)))
& onLeftM returnEarly

-- | Run a transaction that can abort early.
-- todo: rename to runTransactionWithRollback
runTransactionWithRollback2 :: ((forall void. a -> Sqlite.Transaction void) -> Sqlite.Transaction a) -> Cli a
runTransactionWithRollback2 action = do
env <- ask
liftIO (Codebase.runTransactionWithRollback env.codebase action)
Loading
Loading