packages feed

hydra-scala 0.17.3 → 0.17.4

raw patch · 5 files changed

+147/−86 lines, 5 filesdep ~hydra-jvmdep ~hydra-kernelPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: hydra-jvm, hydra-kernel

API changes (from Hackage documentation)

- Hydra.Scala.Coder: constructModule :: t0 -> Graph -> Module -> [Definition] -> Either Error Pkg
+ Hydra.Scala.Coder: constructModule :: Set String -> t0 -> Graph -> Module -> [Definition] -> Either Error Pkg
- Hydra.Scala.Coder: encodeCase :: t0 -> Graph -> Map Name Type -> Maybe Name -> CaseAlternative -> Either Error Case
+ Hydra.Scala.Coder: encodeCase :: Set String -> t0 -> Graph -> Map Name Type -> Maybe Name -> CaseAlternative -> Either Error Case
- Hydra.Scala.Coder: encodeComplexTermDef :: t0 -> Graph -> String -> Term -> Type -> Either Error Stat
+ Hydra.Scala.Coder: encodeComplexTermDef :: Set String -> t0 -> Graph -> String -> Term -> Type -> Either Error Stat
- Hydra.Scala.Coder: encodeFunction :: t0 -> Graph -> Map Name Term -> Term -> Maybe Term -> Either Error Data
+ Hydra.Scala.Coder: encodeFunction :: Set String -> t0 -> Graph -> Map Name Term -> Term -> Maybe Term -> Either Error Data
- Hydra.Scala.Coder: encodeLetBinding :: t0 -> Graph -> Set Name -> Binding -> Either Error Stat
+ Hydra.Scala.Coder: encodeLetBinding :: Set String -> t0 -> Graph -> Set Name -> Binding -> Either Error Stat
- Hydra.Scala.Coder: encodeLocalDef :: t0 -> Graph -> Set Name -> String -> Term -> Type -> Either Error Stat
+ Hydra.Scala.Coder: encodeLocalDef :: Set String -> t0 -> Graph -> Set Name -> String -> Term -> Type -> Either Error Stat
- Hydra.Scala.Coder: encodeTerm :: t0 -> Graph -> Term -> Either Error Data
+ Hydra.Scala.Coder: encodeTerm :: Set String -> t0 -> Graph -> Term -> Either Error Data
- Hydra.Scala.Coder: encodeTermDefinition :: t0 -> Graph -> TermDefinition -> Either Error Stat
+ Hydra.Scala.Coder: encodeTermDefinition :: Set String -> t0 -> Graph -> TermDefinition -> Either Error Stat
- Hydra.Scala.Coder: encodeUntypeApplicationTerm :: InferenceContext -> Graph -> Term -> Either Error Data
+ Hydra.Scala.Coder: encodeUntypeApplicationTerm :: Set String -> InferenceContext -> Graph -> Term -> Either Error Data
- Hydra.Scala.Coder: findImports :: t0 -> Graph -> Module -> Either Error [Stat]
+ Hydra.Scala.Coder: findImports :: Set String -> t0 -> Graph -> Module -> Either Error [Stat]
- Hydra.Scala.Coder: moduleToScala :: Module -> [Definition] -> t0 -> Graph -> Either Error (Map String String)
+ Hydra.Scala.Coder: moduleToScala :: Set String -> Module -> [Definition] -> t0 -> Graph -> Either Error (Map String String)
- Hydra.Scala.Coder: toPrimImport :: ModuleName -> Stat
+ Hydra.Scala.Coder: toPrimImport :: Set String -> ModuleName -> Stat
- Hydra.Scala.Utils: sprim :: Name -> Data
+ Hydra.Scala.Utils: sprim :: Set String -> Name -> Data

Files

CHANGELOG.md view
@@ -15,6 +15,46 @@  --- +## [0.17.3] - 2026-08-01++Point release on the 0.17.x line, focused on **release-artifact integrity**. The 0.17.2 release shipped+two defects that every existing check missed because they validated only the generated `dist/` tree, never+the packaged artifact: the `hydra-build` sdist shipped 3 of 8 modules, and the published Java `hydra-kernel`+jar was a whole [#417](https://github.com/CategoricalData/hydra/issues/417) rename behind. This release adds+an artifact-level publish-completeness gate that inspects the actual uploaded archive, closing that class of+defect across all five registries.++### Highlights++- **Artifact-content completeness gate** ([#621](https://github.com/CategoricalData/hydra/issues/621)):+  every publish path (Hackage sdist, Maven-Java jar, Maven-Scala jar, PyPI wheel, npm tarball) now inspects+  the *packaged* archive and hard-fails if any module a package's manifest declares is missing. The gate also+  asserts the post-#417 class names are present in the Java kernel jar.++### Bug fixes++- **PyPI wheels dropped non-`hydra.*` roots** ([#621](https://github.com/CategoricalData/hydra/issues/621)):+  the wheel packaging hardcoded `packages = ["src/main/python/hydra"]`, silently omitting `hydra-pg`'s+  `com.gdblab.*` and `openGql.*` modules. The generator now ships every emitted top-level root.++### Improvements++- **CI guard for dist-tree completeness** ([#524](https://github.com/CategoricalData/hydra/issues/524)):+  asserts every manifest `mainModules` namespace is emitted into `dist/haskell`, catching the 0.17.2+  `hydra-build` truncation at the tree level (the artifact gate is the packaged-archive counterpart).+- **Manifest generation extracted** into `Hydra.ManifestGeneration`, and the structurally-unneeded #607+  sed shims dropped ([#622](https://github.com/CategoricalData/hydra/issues/622)).+- **Release-verification signing fix** ([#441](https://github.com/CategoricalData/hydra/issues/441)):+  sign the reproducible uncompressed `.tar` and verify the `.asc` against the GitHub Release asset.+- **Java CI signing gate** ([#591](https://github.com/CategoricalData/hydra/issues/591)): `publishToMavenLocal`+  skips gpg signing when no key is present.++### Internal++- Version bump to 0.17.3; `hostVersion` advanced to 0.17.2 and the temporary #417 Java/Python local-host+  shims removed now that 0.17.2 is published on the registries+  ([#417](https://github.com/CategoricalData/hydra/issues/417)).+ ## [0.17.2] - 2026-07-28  Point release on the 0.17.x line. Themes: promotion of the generator's routing and manifest
hydra-scala.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hydra-scala-version:        0.17.3+version:        0.17.4 synopsis:       Hydra's Scala coder: emit Scala source from Hydra modules description:    Hydra is an implementation of the LambdaGraph data model, which takes advantage of an isomorphism between labeled hypergraphs and typed lambda calculus: in Hydra, "graphs are programs, and programs are graphs". Scala support for Hydra category:       Data@@ -40,7 +40,7 @@   build-depends:       base >=4.19.0 && <4.22     , containers >=0.6.7 && <0.8-    , hydra-jvm ==0.17.3-    , hydra-kernel ==0.17.3+    , hydra-jvm ==0.17.4+    , hydra-kernel ==0.17.4     , scientific >=0.3.7 && <0.4   default-language: Haskell2010
src/main/haskell/Hydra/Dsl/Scala/Syntax.hs view
@@ -5,7 +5,6 @@ module Hydra.Dsl.Scala.Syntax where  import qualified Hydra.Core as Core-import qualified Hydra.Dsl.Core as DslCore import qualified Hydra.Scala.Syntax as Syntax import qualified Hydra.Typed as Typed import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
src/main/haskell/Hydra/Scala/Coder.hs view
@@ -107,8 +107,8 @@       _ -> Sets.empty  -- | Construct a Scala package from a Hydra module and its definitions-constructModule :: t0 -> Graph.Graph -> Packaging.Module -> [Packaging.Definition] -> Either Errors.Error Syntax.Pkg-constructModule cx g mod defs =+constructModule :: S.Set String -> t0 -> Graph.Graph -> Packaging.Module -> [Packaging.Definition] -> Either Errors.Error Syntax.Pkg+constructModule overlaySubs cx g mod defs =        let partitioned = Environment.partitionDefinitions defs           typeDefs = Pairs.first partitioned@@ -117,7 +117,7 @@           pname = Syntax.NameData {                 Syntax.nameDataValue = (Syntax.PredefString (Strings.join "." (Strings.splitOn "." nsName)))}           pref = Syntax.RefDataName pname-      in (Eithers.bind (Eithers.mapList (\td -> encodeTypeDefinition cx g td) typeDefs) (\typeDeclStats -> Eithers.bind (Eithers.mapList (\td -> encodeTermDefinition cx g td) termDefs) (\termDeclStats -> Eithers.bind (findImports cx g mod) (\imports -> Right (Syntax.Pkg {+      in (Eithers.bind (Eithers.mapList (\td -> encodeTypeDefinition cx g td) typeDefs) (\typeDeclStats -> Eithers.bind (Eithers.mapList (\td -> encodeTermDefinition overlaySubs cx g td) termDefs) (\termDeclStats -> Eithers.bind (findImports overlaySubs cx g mod) (\imports -> Right (Syntax.Pkg {         Syntax.pkgName = pname,         Syntax.pkgRef = pref,         Syntax.pkgStats = (Lists.concat [@@ -202,8 +202,8 @@       _ -> t)  -- | Encode a case branch-encodeCase :: t0 -> Graph.Graph -> M.Map Core.Name Core.Type -> Maybe Core.Name -> Core.CaseAlternative -> Either Errors.Error Syntax.Case-encodeCase cx g ftypes sn f =+encodeCase :: S.Set String -> t0 -> Graph.Graph -> M.Map Core.Name Core.Type -> Maybe Core.Name -> Core.CaseAlternative -> Either Errors.Error Syntax.Case+encodeCase overlaySubs cx g ftypes sn f =        let fname = Core.caseAlternativeName f           fterm = Core.caseAlternativeHandler f@@ -248,14 +248,14 @@                     Syntax.extractPatFun = (Utils.sname (Utils.qualifyUnionFieldName "MATCHED." sn fname)),                     Syntax.extractPatArgs = patArgs})           applied = applyVar fterm v-      in (Eithers.bind (encodeTerm cx g applied) (\body -> Right (Syntax.Case {+      in (Eithers.bind (encodeTerm overlaySubs cx g applied) (\body -> Right (Syntax.Case {         Syntax.casePat = pat,         Syntax.caseCond = Nothing,         Syntax.caseBody = body})))  -- | Encode a complex term definition with proper parameter types from the type signature-encodeComplexTermDef :: t0 -> Graph.Graph -> String -> Core.Term -> Core.Type -> Either Errors.Error Syntax.Stat-encodeComplexTermDef cx g lname term typ =+encodeComplexTermDef :: S.Set String -> t0 -> Graph.Graph -> String -> Core.Term -> Core.Type -> Either Errors.Error Syntax.Stat+encodeComplexTermDef overlaySubs cx g lname term typ =        let doms = extractDomains typ           paramNames = extractParams term@@ -276,12 +276,12 @@                     Graph.graphPrimitives = (Graph.graphPrimitives g),                     Graph.graphSchemaTypes = (Graph.graphSchemaTypes g),                     Graph.graphTypeVariables = (Sets.union (Sets.fromList freeTypeVars) (Graph.graphTypeVariables g))}-      in (Eithers.bind (Eithers.mapList (encodeTypedParam cx gWithTypeVars) zippedParams) (\sparams -> Eithers.bind (encodeTerm cx gWithTypeVars (extractBody term)) (\sbody -> Eithers.bind (encodeType cx g cod) (\scod ->+      in (Eithers.bind (Eithers.mapList (encodeTypedParam cx gWithTypeVars) zippedParams) (\sparams -> Eithers.bind (encodeTerm overlaySubs cx gWithTypeVars (extractBody term)) (\sbody -> Eithers.bind (encodeType cx g cod) (\scod ->         let gForLets =                 Logic.ifElse (Lists.null letBindings) gWithTypeVars (Scoping.extendGraphForLet (\g2 -> \b -> Logic.ifElse (Predicates.isComplexBinding g2 b) (Just (Core.TermLiteral (Core.LiteralBoolean True))) Nothing) gWithTypeVars (Core.Let {                   Core.letBindings = letBindings,                   Core.letBody = (Core.TermVariable (Core.Name "dummy"))}))-        in (Eithers.bind (Eithers.mapList (encodeLetBinding cx gForLets (Sets.fromList freeTypeVars)) letBindings) (\sbindings ->+        in (Eithers.bind (Eithers.mapList (encodeLetBinding overlaySubs cx gForLets (Sets.fromList freeTypeVars)) letBindings) (\sbindings ->           let defBody =                   Logic.ifElse (Lists.null sbindings) sbody (Syntax.DataBlock (Syntax.BlockData {                     Syntax.blockDataStats = (Lists.concat2 sbindings [@@ -297,8 +297,8 @@             Syntax.defDefnBody = defBody}))))))))))  -- | Encode a Hydra function-valued term (lambda, project, cases, or unwrap) as a Scala expression-encodeFunction :: t0 -> Graph.Graph -> M.Map Core.Name Core.Term -> Core.Term -> Maybe Core.Term -> Either Errors.Error Syntax.Data-encodeFunction cx g meta funTerm arg =+encodeFunction :: S.Set String -> t0 -> Graph.Graph -> M.Map Core.Name Core.Term -> Core.Term -> Maybe Core.Term -> Either Errors.Error Syntax.Data+encodeFunction overlaySubs cx g meta funTerm arg =     case (Strip.deannotateAndDetypeTerm funTerm) of       Core.TermLambda v0 ->         let param = Core.lambdaParameter v0@@ -312,8 +312,8 @@                                   Sets.fromList (Lists.filter (\n -> Logic.not (Lists.member 46 (Strings.toList (Core.unName n)))) (Sets.toList freeVars))                           unresolvedVars = Sets.difference unqualifiedFreeVars (Graph.graphTypeVariables g)                       in (Logic.ifElse (Sets.null unresolvedVars) (Just dom) Nothing))-        in (Eithers.bind (encodeTerm cx g body) (\sbody -> Eithers.bind (Optionals.cases mdom (findSdom cx g meta) (\dom -> Eithers.bind (encodeType cx g dom) (\sdom -> Right (Just sdom)))) (\sdom -> Right (Utils.slambda v sbody sdom))))-      Core.TermUnwrap _ -> Optionals.cases arg (Eithers.bind (findSdom cx g meta) (\sdom -> Right (Utils.slambda "x" (Utils.sname "x") sdom))) (\a -> encodeTerm cx g a)+        in (Eithers.bind (encodeTerm overlaySubs cx g body) (\sbody -> Eithers.bind (Optionals.cases mdom (findSdom cx g meta) (\dom -> Eithers.bind (encodeType cx g dom) (\sdom -> Right (Just sdom)))) (\sdom -> Right (Utils.slambda v sbody sdom))))+      Core.TermUnwrap _ -> Optionals.cases arg (Eithers.bind (findSdom cx g meta) (\sdom -> Right (Utils.slambda "x" (Utils.sname "x") sdom))) (\a -> encodeTerm overlaySubs cx g a)       Core.TermProject v0 ->         let fname = Utils.scalaEscapeName (Core.unName (Core.projectionFieldName v0))             typeName = Core.projectionTypeName v0@@ -321,7 +321,7 @@         in (Optionals.cases arg (Eithers.bind (Eithers.either (\_ -> Right Nothing) (\msdom -> Right msdom) (findSdom cx g meta)) (\msdom -> Right (Utils.slambda pv (Syntax.DataRef (Syntax.RefDataSelect (Syntax.SelectData {           Syntax.selectDataQual = (Utils.sname pv),           Syntax.selectDataName = Syntax.NameData {-            Syntax.nameDataValue = (Syntax.PredefString fname)}}))) msdom))) (\a -> Eithers.bind (encodeTerm cx g a) (\sa -> Right (Syntax.DataRef (Syntax.RefDataSelect (Syntax.SelectData {+            Syntax.nameDataValue = (Syntax.PredefString fname)}}))) msdom))) (\a -> Eithers.bind (encodeTerm overlaySubs cx g a) (\sa -> Right (Syntax.DataRef (Syntax.RefDataSelect (Syntax.SelectData {           Syntax.selectDataQual = sa,           Syntax.selectDataName = Syntax.NameData {             Syntax.nameDataValue = (Syntax.PredefString fname)}}))))))@@ -333,20 +333,20 @@             cases = Core.caseStatementCases v0             dflt = Core.caseStatementDefault v0             ftypes = Eithers.either (\_ -> Maps.empty) (\x_ -> x_) (Resolution.fieldTypes cx g dom)-        in (Eithers.bind (Eithers.mapList (\f -> encodeCase cx g ftypes sn f) cases) (\fieldCases -> Eithers.bind (Optionals.cases dflt (Right fieldCases) (\dfltTerm -> Eithers.bind (encodeTerm cx g dfltTerm) (\sdflt -> Right (Lists.concat2 fieldCases [+        in (Eithers.bind (Eithers.mapList (\f -> encodeCase overlaySubs cx g ftypes sn f) cases) (\fieldCases -> Eithers.bind (Optionals.cases dflt (Right fieldCases) (\dfltTerm -> Eithers.bind (encodeTerm overlaySubs cx g dfltTerm) (\sdflt -> Right (Lists.concat2 fieldCases [           Syntax.Case {             Syntax.casePat = Syntax.PatWildcard,             Syntax.caseCond = Nothing,             Syntax.caseBody = sdflt}])))) (\scases -> Optionals.cases arg (Eithers.bind (findSdom cx g meta) (\sdom -> Right (Utils.slambda v (Syntax.DataMatch (Syntax.MatchData {           Syntax.matchDataExpr = (Utils.sname v),-          Syntax.matchDataCases = scases})) sdom))) (\a -> Eithers.bind (encodeTerm cx g a) (\sa -> Right (Syntax.DataMatch (Syntax.MatchData {+          Syntax.matchDataCases = scases})) sdom))) (\a -> Eithers.bind (encodeTerm overlaySubs cx g a) (\sa -> Right (Syntax.DataMatch (Syntax.MatchData {           Syntax.matchDataExpr = sa,           Syntax.matchDataCases = scases})))))))       _ -> Left (Errors.ErrorOther (Errors.OtherError "unsupported function"))  -- | Encode a let binding as a val or def declaration. outerTypeVars are type params from the enclosing scope.-encodeLetBinding :: t0 -> Graph.Graph -> S.Set Core.Name -> Core.Binding -> Either Errors.Error Syntax.Stat-encodeLetBinding cx g outerTypeVars b =+encodeLetBinding :: S.Set String -> t0 -> Graph.Graph -> S.Set Core.Name -> Core.Binding -> Either Errors.Error Syntax.Stat+encodeLetBinding overlaySubs cx g outerTypeVars b =        let bname = Utils.scalaEscapeName (Core.unName (Core.bindingName b))           bterm = Core.bindingTerm b@@ -358,7 +358,7 @@                       Core.TypeFunction _ -> True                       _ -> False                     _ -> False)-      in (Optionals.cases mts (Eithers.bind (encodeTerm cx g bterm) (\srhs -> Right (Syntax.StatDefn (Syntax.DefnVal (Syntax.ValDefn {+      in (Optionals.cases mts (Eithers.bind (encodeTerm overlaySubs cx g bterm) (\srhs -> Right (Syntax.StatDefn (Syntax.DefnVal (Syntax.ValDefn {         Syntax.valDefnMods = [           Syntax.ModLazy],         Syntax.valDefnPats = [@@ -369,7 +369,7 @@         Syntax.valDefnRhs = srhs}))))) (\ts ->         let newVars = Lists.filter (\v -> Logic.not (Sets.member v outerTypeVars)) (Core.typeSchemeVariables ts)             useDef = Logic.or isFn (Logic.not (Lists.null newVars))-        in (Logic.ifElse useDef (encodeLocalDef cx g outerTypeVars bname bterm (Core.typeSchemeBody ts)) (Eithers.bind (encodeTerm cx g bterm) (\srhs -> Eithers.bind (encodeType cx g (Core.typeSchemeBody ts)) (\styp -> Right (Syntax.StatDefn (Syntax.DefnVal (Syntax.ValDefn {+        in (Logic.ifElse useDef (encodeLocalDef overlaySubs cx g outerTypeVars bname bterm (Core.typeSchemeBody ts)) (Eithers.bind (encodeTerm overlaySubs cx g bterm) (\srhs -> Eithers.bind (encodeType cx g (Core.typeSchemeBody ts)) (\styp -> Right (Syntax.StatDefn (Syntax.DefnVal (Syntax.ValDefn {           Syntax.valDefnMods = [             Syntax.ModLazy],           Syntax.valDefnPats = [@@ -405,8 +405,8 @@       _ -> Left (Errors.ErrorOther (Errors.OtherError "unexpected literal"))  -- | Encode a local def. outerTypeVars are type params already in scope (don't redeclare them).-encodeLocalDef :: t0 -> Graph.Graph -> S.Set Core.Name -> String -> Core.Term -> Core.Type -> Either Errors.Error Syntax.Stat-encodeLocalDef cx g outerTypeVars lname term typ =+encodeLocalDef :: S.Set String -> t0 -> Graph.Graph -> S.Set Core.Name -> String -> Core.Term -> Core.Type -> Either Errors.Error Syntax.Stat+encodeLocalDef overlaySubs cx g outerTypeVars lname term typ =        let freeTypeVars =               Lists.filter (\v -> Logic.and (Logic.not (Lists.member 46 (Strings.toList (Core.unName v)))) (Logic.not (Sets.member v outerTypeVars))) (Sets.toList (Variables.freeVariablesInType typ))@@ -428,12 +428,12 @@                     Graph.graphPrimitives = (Graph.graphPrimitives g),                     Graph.graphSchemaTypes = (Graph.graphSchemaTypes g),                     Graph.graphTypeVariables = (Sets.union allTypeVars (Graph.graphTypeVariables g))}-      in (Eithers.bind (Eithers.mapList (encodeTypedParam cx gWithTypeVars) zippedParams) (\sparams -> Eithers.bind (encodeTerm cx gWithTypeVars (extractBody term)) (\sbody -> Eithers.bind (encodeType cx gWithTypeVars cod) (\scod ->+      in (Eithers.bind (Eithers.mapList (encodeTypedParam cx gWithTypeVars) zippedParams) (\sparams -> Eithers.bind (encodeTerm overlaySubs cx gWithTypeVars (extractBody term)) (\sbody -> Eithers.bind (encodeType cx gWithTypeVars cod) (\scod ->         let gForLets =                 Logic.ifElse (Lists.null letBindings) gWithTypeVars (Scoping.extendGraphForLet (\g2 -> \b -> Logic.ifElse (Predicates.isComplexBinding g2 b) (Just (Core.TermLiteral (Core.LiteralBoolean True))) Nothing) gWithTypeVars (Core.Let {                   Core.letBindings = letBindings,                   Core.letBody = (Core.TermVariable (Core.Name "dummy"))}))-        in (Eithers.bind (Eithers.mapList (encodeLetBinding cx gForLets allTypeVars) letBindings) (\sbindings ->+        in (Eithers.bind (Eithers.mapList (encodeLetBinding overlaySubs cx gForLets allTypeVars) letBindings) (\sbindings ->           let defBody =                   Logic.ifElse (Lists.null sbindings) sbody (Syntax.DataBlock (Syntax.BlockData {                     Syntax.blockDataStats = (Lists.concat2 sbindings [@@ -449,8 +449,8 @@             Syntax.defDefnBody = defBody}))))))))))  -- | Encode a Hydra term as a Scala expression-encodeTerm :: t0 -> Graph.Graph -> Core.Term -> Either Errors.Error Syntax.Data-encodeTerm cx g term0 =+encodeTerm :: S.Set String -> t0 -> Graph.Graph -> Core.Term -> Either Errors.Error Syntax.Data+encodeTerm overlaySubs cx g term0 =        let term = stripWrapEliminations term0       in case (Strip.deannotateTerm term) of@@ -472,12 +472,12 @@               bodyAfterTypeLambdas = Pairs.second tlCollected               substitutedBody = bodyAfterTypeLambdas           in case (Strip.deannotateTerm substitutedBody) of-            Core.TermProject _ -> encodeTerm cx g substitutedBody-            Core.TermCases _ -> encodeTerm cx g substitutedBody-            Core.TermUnwrap _ -> encodeTerm cx g substitutedBody-            Core.TermVariable v1 -> Eithers.bind (correctTypeApps v1 typeArgs g) (\correctedTypeArgs -> Eithers.bind (Eithers.mapList (\targ -> encodeType cx g targ) correctedTypeArgs) (\stypeArgs -> Optionals.cases (Maps.lookup v1 (Graph.graphPrimitives g)) (Eithers.bind (encodeTerm cx g substitutedBody) (\svar -> Right (Utils.sapplyTypes svar stypeArgs))) (\_prim -> Right (Utils.sapplyTypes (Utils.sprim v1) stypeArgs))))-            _ -> encodeTerm cx g substitutedBody-        Core.TermTypeLambda v0 -> encodeTerm cx (Scoping.extendGraphForTypeLambda g v0) (Core.typeLambdaBody v0)+            Core.TermProject _ -> encodeTerm overlaySubs cx g substitutedBody+            Core.TermCases _ -> encodeTerm overlaySubs cx g substitutedBody+            Core.TermUnwrap _ -> encodeTerm overlaySubs cx g substitutedBody+            Core.TermVariable v1 -> Eithers.bind (correctTypeApps v1 typeArgs g) (\correctedTypeArgs -> Eithers.bind (Eithers.mapList (\targ -> encodeType cx g targ) correctedTypeArgs) (\stypeArgs -> Optionals.cases (Maps.lookup v1 (Graph.graphPrimitives g)) (Eithers.bind (encodeTerm overlaySubs cx g substitutedBody) (\svar -> Right (Utils.sapplyTypes svar stypeArgs))) (\_prim -> Right (Utils.sapplyTypes (Utils.sprim overlaySubs v1) stypeArgs))))+            _ -> encodeTerm overlaySubs cx g substitutedBody+        Core.TermTypeLambda v0 -> encodeTerm overlaySubs cx (Scoping.extendGraphForTypeLambda g v0) (Core.typeLambdaBody v0)         Core.TermApplication v0 ->           let fun = Core.applicationFunction v0               arg = Core.applicationArgument v0@@ -488,25 +488,25 @@                 Core.TermApplication v2 ->                   let innerFun = Core.applicationFunction v2                   in case (Strip.deannotateAndDetypeTerm innerFun) of-                    Core.TermCases _ -> encodeFunction cx g (Annotations.termAnnotationInternal innerFun) innerFun (Just arg)-                    _ -> Eithers.bind (encodeTerm cx g fun) (\sfun -> Eithers.bind (encodeTerm cx g arg) (\sarg -> Right (Utils.sapply sfun [+                    Core.TermCases _ -> encodeFunction overlaySubs cx g (Annotations.termAnnotationInternal innerFun) innerFun (Just arg)+                    _ -> Eithers.bind (encodeTerm overlaySubs cx g fun) (\sfun -> Eithers.bind (encodeTerm overlaySubs cx g arg) (\sarg -> Right (Utils.sapply sfun [                       sarg])))-                _ -> Eithers.bind (encodeTerm cx g fun) (\sfun -> Eithers.bind (encodeTerm cx g arg) (\sarg -> Right (Utils.sapply sfun [+                _ -> Eithers.bind (encodeTerm overlaySubs cx g fun) (\sfun -> Eithers.bind (encodeTerm overlaySubs cx g arg) (\sarg -> Right (Utils.sapply sfun [                   sarg])))             Core.TermProject v1 ->               let fname = Utils.scalaEscapeName (Core.unName (Core.projectionFieldName v1))-              in (Eithers.bind (encodeTerm cx g arg) (\sarg -> Right (Syntax.DataRef (Syntax.RefDataSelect (Syntax.SelectData {+              in (Eithers.bind (encodeTerm overlaySubs cx g arg) (\sarg -> Right (Syntax.DataRef (Syntax.RefDataSelect (Syntax.SelectData {                 Syntax.selectDataQual = sarg,                 Syntax.selectDataName = Syntax.NameData {                   Syntax.nameDataValue = (Syntax.PredefString fname)}})))))-            Core.TermCases _ -> encodeFunction cx g (Annotations.termAnnotationInternal fun) fun (Just arg)-            _ -> Eithers.bind (encodeTerm cx g fun) (\sfun -> Eithers.bind (encodeTerm cx g arg) (\sarg -> Right (Utils.sapply sfun [+            Core.TermCases _ -> encodeFunction overlaySubs cx g (Annotations.termAnnotationInternal fun) fun (Just arg)+            _ -> Eithers.bind (encodeTerm overlaySubs cx g fun) (\sfun -> Eithers.bind (encodeTerm overlaySubs cx g arg) (\sarg -> Right (Utils.sapply sfun [               sarg])))-        Core.TermLambda _ -> encodeFunction cx g (Annotations.termAnnotationInternal term) term Nothing-        Core.TermProject _ -> encodeFunction cx g (Annotations.termAnnotationInternal term) term Nothing-        Core.TermCases _ -> encodeFunction cx g (Annotations.termAnnotationInternal term) term Nothing-        Core.TermUnwrap _ -> encodeFunction cx g (Annotations.termAnnotationInternal term) term Nothing-        Core.TermList v0 -> Eithers.bind (Eithers.mapList (\e -> encodeTerm cx g e) v0) (\sels -> Right (Utils.sapply (Utils.sname "Seq") sels))+        Core.TermLambda _ -> encodeFunction overlaySubs cx g (Annotations.termAnnotationInternal term) term Nothing+        Core.TermProject _ -> encodeFunction overlaySubs cx g (Annotations.termAnnotationInternal term) term Nothing+        Core.TermCases _ -> encodeFunction overlaySubs cx g (Annotations.termAnnotationInternal term) term Nothing+        Core.TermUnwrap _ -> encodeFunction overlaySubs cx g (Annotations.termAnnotationInternal term) term Nothing+        Core.TermList v0 -> Eithers.bind (Eithers.mapList (\e -> encodeTerm overlaySubs cx g e) v0) (\sels -> Right (Utils.sapply (Utils.sname "Seq") sels))         Core.TermLiteral v0 -> Eithers.bind (encodeLiteral cx g v0) (\slit ->           let litData = Syntax.DataLit slit           in case v0 of@@ -519,16 +519,16 @@                 Syntax.DataLit (Syntax.LitString (Literals.showBigint (Literals.uint64ToBigint v2)))])               _ -> Right litData             _ -> Right litData)-        Core.TermMap v0 -> Eithers.bind (Eithers.mapList (\kv -> Eithers.bind (encodeTerm cx g (Pairs.first kv)) (\sk -> Eithers.bind (encodeTerm cx g (Pairs.second kv)) (\sv -> Right (Utils.sassign sk sv)))) (Maps.toList v0)) (\spairs -> Right (Utils.sapply (Utils.sname "Map") spairs))-        Core.TermWrap v0 -> encodeTerm cx g (Core.wrappedTermBody v0)-        Core.TermOptional v0 -> Optionals.cases v0 (Right (Utils.sname "None")) (\t -> Eithers.bind (encodeTerm cx g t) (\s -> Right (Utils.sapply (Utils.sname "Some") [+        Core.TermMap v0 -> Eithers.bind (Eithers.mapList (\kv -> Eithers.bind (encodeTerm overlaySubs cx g (Pairs.first kv)) (\sk -> Eithers.bind (encodeTerm overlaySubs cx g (Pairs.second kv)) (\sv -> Right (Utils.sassign sk sv)))) (Maps.toList v0)) (\spairs -> Right (Utils.sapply (Utils.sname "Map") spairs))+        Core.TermWrap v0 -> encodeTerm overlaySubs cx g (Core.wrappedTermBody v0)+        Core.TermOptional v0 -> Optionals.cases v0 (Right (Utils.sname "None")) (\t -> Eithers.bind (encodeTerm overlaySubs cx g t) (\s -> Right (Utils.sapply (Utils.sname "Some") [           s])))         Core.TermRecord v0 ->           let rname = Core.recordTypeName v0               fields = Core.recordFields v0               n = Utils.scalaTypeName True rname-          in (Eithers.bind (Eithers.mapList (\f -> encodeTerm cx g (Core.fieldTerm f)) fields) (\args -> Right (Utils.sapply (Utils.sname n) args)))-        Core.TermSet v0 -> Eithers.bind (Eithers.mapList (\e -> encodeTerm cx g e) (Sets.toList v0)) (\sels -> Right (Utils.sapply (Utils.sname "scala.collection.immutable.Set") sels))+          in (Eithers.bind (Eithers.mapList (\f -> encodeTerm overlaySubs cx g (Core.fieldTerm f)) fields) (\args -> Right (Utils.sapply (Utils.sname n) args)))+        Core.TermSet v0 -> Eithers.bind (Eithers.mapList (\e -> encodeTerm overlaySubs cx g e) (Sets.toList v0)) (\sels -> Right (Utils.sapply (Utils.sname "scala.collection.immutable.Set") sels))         Core.TermInject v0 ->           let sn = Core.injectionTypeName v0               fn = Core.fieldName (Core.injectionField v0)@@ -541,9 +541,9 @@             _ -> False) (\dom -> case (Strip.deannotateType dom) of             Core.TypeUnit -> True             Core.TypeRecord v1 -> Equality.equal (Lists.length v1) 0-            _ -> False)) (Right lhs) (Eithers.bind (encodeTerm cx g ft) (\sarg -> Right (Utils.sapply lhs [+            _ -> False)) (Right lhs) (Eithers.bind (encodeTerm overlaySubs cx g ft) (\sarg -> Right (Utils.sapply lhs [             sarg]))))-        Core.TermVariable v0 ->+        Core.TermVariable v0 -> Optionals.cases (Maps.lookup v0 (Graph.graphPrimitives g)) (           let fullName = Core.unName v0               localName = Names.localNameOf v0               parts = Strings.splitOn "." fullName@@ -551,12 +551,12 @@               escaped =                       Logic.ifElse (Ordering.lte numParts 1) (Utils.scalaEscapeName fullName) (Logic.ifElse (Equality.equal numParts 2) (Strings.concat2 (Optionals.withDefault fullName (Lists.head parts)) (Strings.concat2 "." (Utils.scalaEscapeName localName))) (Strings.join "." (Lists.concat2 (Lists.take (Math.sub numParts 1) parts) [                         Utils.scalaEscapeName localName])))-          in (Right (Utils.sname escaped))-        Core.TermAnnotated v0 -> encodeTerm cx g (Core.annotatedTermBody v0)-        Core.TermEither v0 -> Eithers.either (\l -> Eithers.bind (encodeTerm cx g l) (\sl -> Right (Utils.sapply (Utils.sname "Left") [-          sl]))) (\r -> Eithers.bind (encodeTerm cx g r) (\sr -> Right (Utils.sapply (Utils.sname "Right") [+          in (Right (Utils.sname escaped))) (\_prim -> Right (Utils.sprim overlaySubs v0))+        Core.TermAnnotated v0 -> encodeTerm overlaySubs cx g (Core.annotatedTermBody v0)+        Core.TermEither v0 -> Eithers.either (\l -> Eithers.bind (encodeTerm overlaySubs cx g l) (\sl -> Right (Utils.sapply (Utils.sname "Left") [+          sl]))) (\r -> Eithers.bind (encodeTerm overlaySubs cx g r) (\sr -> Right (Utils.sapply (Utils.sname "Right") [           sr]))) v0-        Core.TermPair v0 -> Eithers.bind (encodeTerm cx g (Pairs.first v0)) (\sf -> Eithers.bind (encodeTerm cx g (Pairs.second v0)) (\ss -> Right (Utils.sapply (Utils.sname "Tuple2") [+        Core.TermPair v0 -> Eithers.bind (encodeTerm overlaySubs cx g (Pairs.first v0)) (\sf -> Eithers.bind (encodeTerm overlaySubs cx g (Pairs.second v0)) (\ss -> Right (Utils.sapply (Utils.sname "Tuple2") [           sf,           ss])))         Core.TermUnit -> Right (Syntax.DataLit Syntax.LitUnit)@@ -565,14 +565,14 @@               body = Core.letBody v0               gLet =                       Scoping.extendGraphForLet (\g2 -> \b -> Logic.ifElse (Predicates.isComplexBinding g2 b) (Just (Core.TermLiteral (Core.LiteralBoolean True))) Nothing) g v0-          in (Eithers.bind (Eithers.mapList (encodeLetBinding cx gLet (Graph.graphTypeVariables gLet)) bindings) (\sbindings -> Eithers.bind (encodeTerm cx gLet body) (\sbody -> Right (Syntax.DataBlock (Syntax.BlockData {+          in (Eithers.bind (Eithers.mapList (encodeLetBinding overlaySubs cx gLet (Graph.graphTypeVariables gLet)) bindings) (\sbindings -> Eithers.bind (encodeTerm overlaySubs cx gLet body) (\sbody -> Right (Syntax.DataBlock (Syntax.BlockData {             Syntax.blockDataStats = (Lists.concat2 sbindings [               Syntax.StatTerm sbody])})))))         _ -> Left (Errors.ErrorOther (Errors.OtherError "unexpected term"))  -- | Encode a term definition as a Scala statement-encodeTermDefinition :: t0 -> Graph.Graph -> Packaging.TermDefinition -> Either Errors.Error Syntax.Stat-encodeTermDefinition cx g td =+encodeTermDefinition :: S.Set String -> t0 -> Graph.Graph -> Packaging.TermDefinition -> Either Errors.Error Syntax.Stat+encodeTermDefinition overlaySubs cx g td =        let name = Packaging.termDefinitionName td           term = Packaging.termDefinitionBody td@@ -588,7 +588,7 @@                     _ -> False           freeTypeVarsInTyp =                   Lists.filter (\v -> Logic.not (Lists.member 46 (Strings.toList (Core.unName v)))) (Sets.toList (Variables.freeVariablesInType typ_))-      in (Logic.ifElse isFunctionType (encodeComplexTermDef cx g lname term typ_) (Logic.ifElse (Lists.null freeTypeVarsInTyp) (Eithers.bind (encodeType cx g typ_) (\stype -> Eithers.bind (encodeTerm cx g term) (\rhs -> Right (Syntax.StatDefn (Syntax.DefnVal (Syntax.ValDefn {+      in (Logic.ifElse isFunctionType (encodeComplexTermDef overlaySubs cx g lname term typ_) (Logic.ifElse (Lists.null freeTypeVarsInTyp) (Eithers.bind (encodeType cx g typ_) (\stype -> Eithers.bind (encodeTerm overlaySubs cx g term) (\rhs -> Right (Syntax.StatDefn (Syntax.DefnVal (Syntax.ValDefn {         Syntax.valDefnMods = [           Syntax.ModLazy],         Syntax.valDefnPats = [@@ -596,7 +596,7 @@             Syntax.varPatName = Syntax.NameData {               Syntax.nameDataValue = (Syntax.PredefString lname)}})],         Syntax.valDefnDecltpe = (Just stype),-        Syntax.valDefnRhs = rhs})))))) (Eithers.bind (encodeType cx g typ_) (\stype -> Eithers.bind (encodeTerm cx g term) (\rhs ->+        Syntax.valDefnRhs = rhs})))))) (Eithers.bind (encodeType cx g typ_) (\stype -> Eithers.bind (encodeTerm overlaySubs cx g term) (\rhs ->         let tparams = Lists.map (\tv -> Utils.stparam tv) freeTypeVarsInTyp         in (Right (Syntax.StatDefn (Syntax.DefnDef (Syntax.DefDefn {           Syntax.defDefnMods = [],@@ -854,9 +854,9 @@         Syntax.paramDataDefault = Nothing})))  -- | Encode an untyped application term by first inferring types-encodeUntypeApplicationTerm :: Typing.InferenceContext -> Graph.Graph -> Core.Term -> Either Errors.Error Syntax.Data-encodeUntypeApplicationTerm cx g term =-    Eithers.bind (Inference.inferInGraphContext cx g term) (\result -> encodeTerm cx g (Typing.inferenceResultTerm result))+encodeUntypeApplicationTerm :: S.Set String -> Typing.InferenceContext -> Graph.Graph -> Core.Term -> Either Errors.Error Syntax.Data+encodeUntypeApplicationTerm overlaySubs cx g term =+    Eithers.bind (Inference.inferInGraphContext cx g term) (\result -> encodeTerm overlaySubs cx g (Typing.inferenceResultTerm result))  -- | Extract the innermost body from a term extractBody :: Core.Term -> Core.Term@@ -1009,11 +1009,11 @@       _ -> Left (Errors.ErrorOther (Errors.OtherError "expected a function type"))))  -- | Find import statements for the module-findImports :: t0 -> Graph.Graph -> Packaging.Module -> Either Errors.Error [Syntax.Stat]-findImports cx g mod =+findImports :: S.Set String -> t0 -> Graph.Graph -> Packaging.Module -> Either Errors.Error [Syntax.Stat]+findImports overlaySubs cx g mod =     Eithers.bind (Analysis.moduleDependencyModuleNames cx g False False True False mod) (\elImps -> Eithers.bind (Analysis.moduleDependencyModuleNames cx g False True False False mod) (\primImps -> Right (Lists.concat [       Lists.map toElImport (Sets.toList elImps),-      (Lists.map toPrimImport (Sets.toList primImps))])))+      (Lists.map (toPrimImport overlaySubs) (Sets.toList primImps))])))  -- | If t is Pair(var, _), return the first component's variable name (#589) findPairFirst :: Core.Type -> Maybe Core.Name@@ -1058,9 +1058,9 @@ isSimpleName name = Equality.equal (Lists.length (Strings.splitOn "." (Core.unName name))) 1  -- | Convert a Hydra module to Scala source code-moduleToScala :: Packaging.Module -> [Packaging.Definition] -> t0 -> Graph.Graph -> Either Errors.Error (M.Map String String)-moduleToScala mod defs cx g =-    Eithers.bind (constructModule cx g mod defs) (\pkg ->+moduleToScala :: S.Set String -> Packaging.Module -> [Packaging.Definition] -> t0 -> Graph.Graph -> Either Errors.Error (M.Map String String)+moduleToScala overlaySubs mod defs cx g =+    Eithers.bind (constructModule overlaySubs cx g mod defs) (\pkg ->       let s = Serialization.printExpr (Serialization.parenthesize (Serde.pkgToExpr pkg))       in (Right (Maps.singleton (Names.moduleNameToFilePath Util.CaseConventionCamel (File.FileExtension "scala") (Packaging.moduleName mod)) s))) @@ -1152,14 +1152,27 @@             Syntax.ImporteeWildcard]}]}))  -- | Create a primitive import statement-toPrimImport :: Packaging.ModuleName -> Syntax.Stat-toPrimImport ns =-    Syntax.StatImportExport (Syntax.ImportExportStatImport (Syntax.Import {-      Syntax.importImporters = [-        Syntax.Importer {-          Syntax.importerRef = (Syntax.RefDataName (Syntax.NameData {-            Syntax.nameDataValue = (Syntax.PredefString (Strings.join "." (Strings.splitOn "." (Packaging.unModuleName ns))))})),-          Syntax.importerImportees = []}]}))+toPrimImport :: S.Set String -> Packaging.ModuleName -> Syntax.Stat+toPrimImport overlaySubs ns =++      let raw = Packaging.unModuleName ns+          parts = Strings.splitOn "." raw+          sub = Strings.join "." (Lists.drop 2 parts)+          redirected =+                  Logic.ifElse (Logic.and (Logic.and (Equality.equal (Lists.length parts) 3) (Equality.equal (Lists.take 2 parts) [+                    "hydra",+                    "lib"])) (Sets.member sub overlaySubs)) (Strings.concat2 "hydra.overlay.scala.lib." sub) raw+          redirectedName =+                  Syntax.NameData {+                    Syntax.nameDataValue = (Syntax.PredefString (Strings.join "." (Strings.splitOn "." redirected)))}+          redirectedRef = Syntax.RefDataName redirectedName+          redirectedImporter =+                  Syntax.Importer {+                    Syntax.importerRef = redirectedRef,+                    Syntax.importerImportees = []}+      in (Syntax.StatImportExport (Syntax.ImportExportStatImport (Syntax.Import {+        Syntax.importImporters = [+          redirectedImporter]})))  -- | Convert a type parameter to a type variable reference typeParamToTypeVar :: Syntax.ParamType -> Syntax.Type
src/main/haskell/Hydra/Scala/Utils.hs view
@@ -152,11 +152,20 @@ sname s = Syntax.DataRef (Syntax.RefDataName (Syntax.NameData {   Syntax.nameDataValue = (Syntax.PredefString s)})) --- | Create a Scala primitive reference from a Hydra name-sprim :: Core.Name -> Syntax.Data-sprim name =+-- | Create a Scala primitive reference from a Hydra name, redirecting hydra.lib.<sub>.<local> to hydra.overlay.scala.lib.<sub>.<local> when <sub> has an overlay implementation on this host (#630 -- the on-disk overlaySubs existence signal). Unlike toPrimImport (which redirects a bare hydra.lib.<sub> MODULE name, always exactly 3 segments), a primitive reference is hydra.lib.<sub>.<local> -- at least 4 segments, since it also carries the primitive's own local name -- so the sub to check against overlaySubs is parts[2] alone, not the whole post-prefix tail (#635).+sprim :: S.Set String -> Core.Name -> Syntax.Data+sprim overlaySubs name = -      let qname = Names.qualifyName name+      let raw = Core.unName name+          parts = Strings.splitOn "." raw+          sub = Strings.join "." (Lists.drop 2 parts)+          subHead = Optionals.withDefault "" (Lists.at 2 parts)+          redirectedRaw =+                  Logic.ifElse (Logic.and (Logic.and (Ordering.gte (Lists.length parts) 4) (Equality.equal (Lists.take 2 parts) [+                    "hydra",+                    "lib"])) (Sets.member subHead overlaySubs)) (Strings.concat2 "hydra.overlay.scala.lib." sub) raw+          redirectedName = Core.Name redirectedRaw+          qname = Names.qualifyName redirectedName           prefix = Packaging.unModuleName (Optionals.withDefault (Packaging.ModuleName "") (Util.qualifiedNameModuleName qname))           local = scalaEscapeName (Util.qualifiedNameLocal qname)       in (sname (Strings.concat2 (Strings.concat2 prefix ".") local))