From 42865c710daa299d4cee0923936f14329a950685 Mon Sep 17 00:00:00 2001 From: "P. Oscar Boykin" Date: Fri, 13 Dec 2024 16:00:23 -1000 Subject: [PATCH] Refactor more out of PackageMap inferAll to relevant methods (#1319) --- .../main/scala/org/bykn/bosatsu/Package.scala | 52 +++++++++++-------- .../org/bykn/bosatsu/PackageCustoms.scala | 32 ++++++++++++ .../scala/org/bykn/bosatsu/PackageMap.scala | 47 ++++++----------- 3 files changed, 76 insertions(+), 55 deletions(-) diff --git a/core/src/main/scala/org/bykn/bosatsu/Package.scala b/core/src/main/scala/org/bykn/bosatsu/Package.scala index 104e50316..2950fb4d3 100644 --- a/core/src/main/scala/org/bykn/bosatsu/Package.scala +++ b/core/src/main/scala/org/bykn/bosatsu/Package.scala @@ -592,29 +592,35 @@ object Package { } implicit class ResolvedMethods(private val resolved: Resolved) extends AnyVal { - def importName[F[_], A]( - fromPackage: PackageName, - item: ImportedName[Unit] - )(recurse: ResolvedPackage => F[Typed[A]])(implicit F: Applicative[F]): F[Either[PackageError, (Package.Interface, ImportedName[NonEmptyList[Referant[Kind.Arg]]])]] = - Package.unfix(resolved) match { - case Right(p) => - /* - * Here we have a source we need to fully resolve - */ - recurse(p) - .map { packF => - val packInterface = Package.interfaceOf(packF) - packF.getImport(fromPackage, item) - .map((packInterface, _)) - } - case Left(iface) => - /* - * this import is already an interface, we can stop here - */ - // this is very fast and does not need to be done in a thread - F.pure(iface.getImportIface(fromPackage, item) - .map((iface, _))) - } + def name: PackageName = + FixType.unfix(resolved) match { + case Left(iface) => iface.name + case Right(pack) => pack.name + } + + def importName[F[_], A]( + fromPackage: PackageName, + item: ImportedName[Unit] + )(recurse: ResolvedPackage => F[Typed[A]])(implicit F: Applicative[F]): F[Either[PackageError, (Package.Interface, ImportedName[NonEmptyList[Referant[Kind.Arg]]])]] = + Package.unfix(resolved) match { + case Right(p) => + /* + * Here we have a source we need to fully resolve + */ + recurse(p) + .map { packF => + val packInterface = Package.interfaceOf(packF) + packF.getImport(fromPackage, item) + .map((packInterface, _)) + } + case Left(iface) => + /* + * this import is already an interface, we can stop here + */ + // this is very fast and does not need to be done in a thread + F.pure(iface.getImportIface(fromPackage, item) + .map((iface, _))) + } } def orderByName[A, B, C, D]: Order[Package[A, B, C, D]] = diff --git a/core/src/main/scala/org/bykn/bosatsu/PackageCustoms.scala b/core/src/main/scala/org/bykn/bosatsu/PackageCustoms.scala index ea1f0beff..982bf03fb 100644 --- a/core/src/main/scala/org/bykn/bosatsu/PackageCustoms.scala +++ b/core/src/main/scala/org/bykn/bosatsu/PackageCustoms.scala @@ -2,6 +2,7 @@ package org.bykn.bosatsu import cats.data.{ Chain, + Ior, NonEmptyList, NonEmptySet, NonEmptyChain, @@ -29,6 +30,37 @@ object PackageCustoms { noUselessBinds(pack) *> allImportsAreUsed(pack) + /** + * Build the exports and check the customs, and then return the Typed package + */ + def assemble( + nm: PackageName, + ilist: List[Import[Package.Interface, NonEmptyList[Referant[Kind.Arg]]]], + imap: ImportMap[Package.Interface, NonEmptyList[Referant[Kind.Arg]]], + exports: List[ExportedName[Unit]], + program: Program[TypeEnv[Kind.Arg], TypedExpr[Declaration], List[Statement]] + ): Ior[NonEmptyList[PackageError], Package.Typed[Declaration]] = { + + val Program(types, lets, _, _) = program + ExportedName + .buildExports(nm, exports, types, lets) match { + case Validated.Valid(exports) => + // We have a result, which we can continue to check + val pack = Package(nm, ilist, exports, (program, imap)) + // We have to check the "customs" before any normalization + // or optimization + PackageCustoms(pack) match { + case Validated.Valid(p1) => Ior.right(p1) + case Validated.Invalid(errs) => + Ior.both(errs.toNonEmptyList, pack) + } + case Validated.Invalid(unknowns) => + Ior.left(unknowns.map { n => + PackageError.UnknownExport(n, nm, lets): PackageError + }) + } + } + private def removeUnused[A]( vals: Option[NonEmptySet[(PackageName, Identifier)]], types: Option[NonEmptySet[(PackageName, Type.Const)]], diff --git a/core/src/main/scala/org/bykn/bosatsu/PackageMap.scala b/core/src/main/scala/org/bykn/bosatsu/PackageMap.scala index fbd7781d6..6a4cfbbf5 100644 --- a/core/src/main/scala/org/bykn/bosatsu/PackageMap.scala +++ b/core/src/main/scala/org/bykn/bosatsu/PackageMap.scala @@ -123,15 +123,18 @@ object PackageMap { def treeShake[A](p: Typed[A], roots: Set[(PackageName, Identifier)]): Typed[A] = { type Ident = (PackageName, Identifier) - def dependency(a: Ident): Iterable[Ident] = - p.toMap.get(a._1) match { - case Some(pack) => - pack.lets.flatMap { - case (n, _, te) if a._2 === n => te.globals - case _ => Nil + def dependency(a: Ident): Iterable[Ident] = { + val (pn, ident) = a + ident match { + case b: Identifier.Bindable => + p.toMap.get(pn) match { + case Some(pack) => + pack.program._1.getLet(b).toList.flatMap(_._2.globals) + case None => Nil } - case None => Nil + case _ => Nil } + } val keep = Dag.transitiveSet(roots.toList.sorted)(dependency) @@ -402,12 +405,7 @@ object PackageMap { case (Package(nm, imports, exports, (stmt, imps)), recurse) => val nameToRes = imports.iterator.map { i => val resolved: Package.Resolved = i.pack - val name = FixType.unfix(resolved) match { - case Left(iface) => iface.name - case Right(pack) => pack.name - } - - (name, resolved) + (resolved.name, resolved) }.toMap def resolvedImports: ImportMap[Package.Resolved, Unit] = @@ -454,25 +452,10 @@ object PackageMap { } inferBody.flatMap { - case (ilist, imap, (fte, program @ Program(types, lets, _, _))) => - val ior = ExportedName - .buildExports(nm, exports, types, lets) match { - case Validated.Valid(exports) => - // We have a result, which we can continue to check - val pack = Package(nm, ilist, exports, (program, imap)) - // We have to check the "customs" before any normalization - // or optimization - PackageCustoms(pack) match { - case Validated.Valid(p1) => Ior.right((fte, p1)) - case Validated.Invalid(errs) => - val res = (fte, pack) - Ior.both(errs.toNonEmptyList, res) - } - case Validated.Invalid(badPackages) => - Ior.left(badPackages.map { n => - PackageError.UnknownExport(n, nm, lets): PackageError - }) - } + case (ilist, imap, (fte, program)) => + val ior = + PackageCustoms.assemble(nm, ilist, imap, exports, program) + .map((fte, _)) IorT.fromIor(ior) }.value }