Skip to content

Commit

Permalink
Refactor Phase1ReadTypescript. (ScalablyTyped#366)
Browse files Browse the repository at this point in the history
- Don't use phases for files within a library. this is preliminary work for improving javascript modules
- Remove `Key`
  • Loading branch information
oyvindberg authored Oct 10, 2022
1 parent fc76288 commit 84cc76b
Show file tree
Hide file tree
Showing 38 changed files with 715 additions and 911 deletions.
20 changes: 10 additions & 10 deletions cli/src/main/scala/org/scalablytyped/converter/cli/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ object Main {

val packageJson = Json.force[PackageJson](packageJsonPath)

val projectSource: Option[Source.FromFolder] =
if (includeProject) Some(Source.FromFolder(InFolder(inDir), TsIdentLibrary(inDir.last))) else None
val projectSource: Option[LibTsSource.FromFolder] =
if (includeProject) Some(LibTsSource.FromFolder(InFolder(inDir), TsIdentLibrary(inDir.last))) else None

val wantedLibs: SortedSet[TsIdentLibrary] =
libsFromCmdLine match {
Expand All @@ -215,7 +215,7 @@ object Main {

val bootstrapped = Bootstrap.fromNodeModules(InFolder(nodeModulesPath), conversion, wantedLibs)

val sources: Vector[Source.TsLibSource] = {
val sources: Vector[LibTsSource] = {
bootstrapped.initialLibs match {
case Left(unresolved) => sys.error(unresolved.msg)
case Right(initial) => projectSource.foldLeft(initial)(_ :+ _)
Expand Down Expand Up @@ -247,8 +247,8 @@ object Main {
Duration.Inf,
)

val Pipeline: RecPhase[Source, PublishedSbtProject] =
RecPhase[Source]
val Pipeline: RecPhase[LibTsSource, PublishedSbtProject] =
RecPhase[LibTsSource]
.next(
new Phase1ReadTypescript(
calculateLibraryVersion = PackageJsonOnly,
Expand Down Expand Up @@ -291,15 +291,15 @@ object Main {
"build",
)

val results: Map[Source, PhaseRes[Source, PublishedSbtProject]] =
val results: Map[LibTsSource, PhaseRes[LibTsSource, PublishedSbtProject]] =
sources
.map(source => source -> PhaseRunner.go(Pipeline, source, Nil, (_: Source) => logger.void, NoListener))
.map(source => source -> PhaseRunner(Pipeline, (_: LibTsSource) => logger.void, NoListener)(source))
.toMap

val td = System.currentTimeMillis - t0
logger.warn(td)

val failures: Map[Source, Either[Throwable, String]] =
val failures: Map[LibTsSource, Either[Throwable, String]] =
results.collect { case (_, PhaseRes.Failure(errors)) => errors }.reduceOption(_ ++ _).getOrElse(Map.empty)

if (failures.nonEmpty) {
Expand All @@ -317,8 +317,8 @@ object Main {

System.exit(1)
} else {
val allSuccesses: Map[Source, PublishedSbtProject] = {
def go(source: Source, p: PublishedSbtProject): Map[Source, PublishedSbtProject] =
val allSuccesses: Map[LibTsSource, PublishedSbtProject] = {
def go(source: LibTsSource, p: PublishedSbtProject): Map[LibTsSource, PublishedSbtProject] =
Map(source -> p) ++ p.project.deps.flatMap { case (k, v) => go(k, v) }

results.collect { case (s, PhaseRes.Ok(res)) => go(s, res) }.reduceOption(_ ++ _).getOrElse(Map.empty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,28 +437,6 @@ object IArray {
fromArrayAndSize[A](ret, o)
}
}

@inline implicit final class IArrayOptionOps[A <: AnyRef](val as: IArray[Option[A]]) extends AnyRef {
def sequenceOption: Option[IArray[A]] = {
if (as.isEmpty) {
return Some(IArray.Empty)
}

val newArray = Array.ofDim[AnyRef](as.length)
var i = 0
while (i < as.length) {
as(i) match {
case Some(value) => newArray(i) = value
case None => return None
}

i += 1
}

Some(fromArrayAndSize[A](newArray, as.length))
}

}
}

final class IArray[+A <: AnyRef](private val array: Array[AnyRef], val length: Int) extends Serializable { self =>
Expand Down
86 changes: 0 additions & 86 deletions core/src/main/scala/org/scalablytyped/converter/internal/Key.scala

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ object Synced {
final case class InFile(path: os.Path) {
def folder: InFolder =
InFolder(path / os.up)
override val toString: String = path.toString()
}

object InFile {
implicit object InFileKey extends IsKey[InFile]
implicit val ordering: Ordering[InFile] = Ordering.by(_.toString)
}

final case class InFolder(path: os.Path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ object Name {

implicit val OrderedName: Ordering[Name] = Ordering[String].on[Name](_.unescaped)

implicit object NameKey extends IsKey[Name]

def necessaryRewrite(name: Name): Name =
necessaryRewrite(name.unescaped) match {
case Some(rewritten) => Name(rewritten)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,6 @@ final case class PackageTree(
codePath: QualifiedName,
) extends ContainerTree

object PackageTree {
implicit object PackageTreeKey extends Key[PackageTree] {
override type Id = Name
override def apply(t: PackageTree): Id = t.name
}
}

final case class ClassTree(
isImplicit: Boolean,
annotations: IArray[Annotation],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,6 @@ object TsIdent {
implicit val decodes: Decoder[TsIdent] = io.circe013.generic.semiauto.deriveDecoder
implicit val ordering: Ordering[TsIdent] = Ordering[String].on[TsIdent](_.value)

implicit object TsIdentKey extends IsKey[TsIdent]

def apply(str: String): TsIdentSimple =
TsIdentSimple(str)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package org.scalablytyped.converter.internal
package importer

import org.scalablytyped.converter.internal.importer.Source.{FromFolder, StdLibSource, TsLibSource}
import org.scalablytyped.converter.internal.importer.LibTsSource.{FromFolder, StdLibSource}
import org.scalablytyped.converter.internal.seqs._
import org.scalablytyped.converter.internal.ts.{TsIdent, TsIdentLibrary}

import scala.collection.immutable.SortedSet

object Bootstrap {

/**
* At this point we have scanned node_modules (and DT, if in CI) and know the location ([[Source]])
* At this point we have scanned node_modules (and DT, if in CI) and know the location ([[LibTsSource]])
* of all libraries it's possible to import.
*
* @param initialLibs determines if all the libraries explicitly wanted by the user were available
*/
case class Bootstrapped(
inputFolders: IArray[InFolder],
libraryResolver: LibraryResolver,
initialLibs: Either[Unresolved, Vector[TsLibSource]],
initialLibs: Either[Unresolved, Vector[LibTsSource]],
)

def forCi(
Expand All @@ -44,10 +45,10 @@ object Bootstrap {

val libraryResolver = new LibraryResolver(stdLibSource, allSources, conversion.ignoredLibs)

val initial: Either[Unresolved, Vector[TsLibSource]] =
val initial: Either[Unresolved, Vector[LibTsSource]] =
wantedLibs match {
case sets.EmptySet() => Right(allSources.toVector)
case wantedLibs => libraryResolver.resolveAll(wantedLibs)
case wantedLibs => resolveAll(libraryResolver, wantedLibs)
}

Bootstrapped(inputFolders, libraryResolver, initial)
Expand Down Expand Up @@ -80,27 +81,27 @@ object Bootstrap {
val inputFolders: IArray[InFolder] =
IArray.fromOptions(`@types`, Some(fromFolder))

val allSources: IArray[Source.FromFolder] =
val allSources: IArray[LibTsSource.FromFolder] =
findSources(inputFolders)

val libraryResolver = new LibraryResolver(stdLibSource, allSources, conversion.ignoredLibs)

val initialLibs: Either[Unresolved, Vector[TsLibSource]] =
libraryResolver.resolveAll(wantedLibs)
val initialLibs: Either[Unresolved, Vector[LibTsSource]] =
resolveAll(libraryResolver, wantedLibs)

Bootstrapped(inputFolders, libraryResolver, initialLibs)
}

def findSources(folders: IArray[InFolder]): IArray[Source.FromFolder] =
folders.foldLeft[IArray[Source.FromFolder]](IArray.Empty) {
def findSources(folders: IArray[InFolder]): IArray[LibTsSource.FromFolder] =
folders.foldLeft[IArray[LibTsSource.FromFolder]](IArray.Empty) {
case (foundSources, next) =>
val foundNames = foundSources.map(_.libName).toSet
val newSources = forFolder(next).filterNot(s => foundNames(s.libName))

foundSources ++ newSources
}

private def forFolder(folder: InFolder): IArray[Source.FromFolder] =
private def forFolder(folder: InFolder): IArray[LibTsSource.FromFolder] =
IArray.fromTraversable(
os.list(folder.path)
.collect { case dir if os.isDir(dir) => dir }
Expand All @@ -113,9 +114,20 @@ object Bootstrap {
.map(nestedPath => FromFolder(InFolder(nestedPath), TsIdentLibrary(s"${path.last}/${nestedPath.last}")))
case path => List(FromFolder(InFolder(path), TsIdentLibrary(path.last)))
}
.filter(_.hasSources),
.filter(s => LibTsSource.hasTypescriptSources(s.folder)),
)

def resolveAll(
libraryResolver: LibraryResolver,
libs: SortedSet[TsIdentLibrary],
): Either[Unresolved, Vector[LibTsSource]] =
libs.toVector
.map(libraryResolver.library)
.partitionCollect2({ case LibraryResolver.Found(x) => x }, { case LibraryResolver.NotAvailable(name) => name }) match {
case (allFound, Seq(), _) => Right(allFound)
case (_, notAvailable, _) => Left(Unresolved(notAvailable))
}

case class Unresolved(notAvailable: Vector[TsIdentLibrary]) {
def msg =
s"Missing typescript definitions for the following libraries: ${notAvailable.map(_.value).mkString(", ")}. Try to add a corresponding `@types` npm package, or use `stIgnore` to ignore"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.scalablytyped.converter.internal
package importer

import com.olvind.logging.Logger
import org.scalablytyped.converter.internal.importer.Phase1Res.{LibTs, UnpackLibs}
import org.scalablytyped.converter.internal.maps._
import org.scalablytyped.converter.internal.scalajs._
import org.scalablytyped.converter.internal.scalajs.transforms.CleanIllegalNames
Expand All @@ -17,7 +16,7 @@ class ImportTree(
enableScalaJsDefined: Boolean,
) {
def apply(lib: LibTs, logger: Logger[Unit]): PackageTree = {
val deps = UnpackLibs(lib.dependencies).map {
val deps = lib.transitiveDependencies.map {
case (source, depLib) => source -> depLib.parsed
}

Expand Down
Loading

0 comments on commit 84cc76b

Please sign in to comment.