All Downloads are FREE. Search and download functionalities are using the official Maven repository.

izumi.idealingua.il.loader.ModelResolver.scala Maven / Gradle / Ivy

The newest version!
package izumi.idealingua.il.loader

import izumi.fundamentals.platform.exceptions.IzThrowable._
import izumi.idealingua.il.loader.verification.DuplicateDomainsRule
import izumi.idealingua.model.il.ast.IDLTyper
import izumi.idealingua.model.il.ast.raw.domains.DomainMeshResolved
import izumi.idealingua.model.loader._
import izumi.idealingua.model.problems.IDLDiagnostics
import izumi.idealingua.model.problems.TypespaceError.VerificationException
import izumi.idealingua.model.typespace.verification.{TypespaceVerifier, VerificationRule}
import izumi.idealingua.model.typespace.{Typespace, TypespaceImpl}

class ModelResolver(rules: Seq[VerificationRule]) {

  def resolve(domains: UnresolvedDomains): LoadedModels = {
    val globalChecks = Seq(
      DuplicateDomainsRule
    )
    val importResolver = new ExternalRefResolver(domains)

    val typed = domains.domains.results
      .map(importResolver.resolveReferences)
      .map(makeTyped)

    val result = LoadedModels(typed, IDLDiagnostics.empty)

    val postDiag = globalChecks.map(_.check(result.successful)).fold(IDLDiagnostics.empty)(_ ++ _)

    result.withDiagnostics(postDiag)
  }

  private def makeTyped(f: Either[LoadedDomain.Failure, DomainMeshResolved]): LoadedDomain = {
    (for {
      d      <- f
      ts     <- runTyper(d)
      result <- runVerifier(ts)
    } yield {
      result
    }).fold(identity, identity)
  }

  private def runVerifier(ts: Typespace): Either[LoadedDomain.VerificationFailed, LoadedDomain.Success] = {
    try {
      val issues = new TypespaceVerifier(ts, rules).verify()
      if (issues.issues.isEmpty) {
        Right(LoadedDomain.Success(ts.domain.meta.origin, ts, issues.warnings))
      } else {
        Left(LoadedDomain.VerificationFailed(ts.domain.meta.origin, ts.domain.id, issues))
      }
    } catch {
      case t: Throwable =>
        Left(LoadedDomain.VerificationFailed(ts.domain.meta.origin, ts.domain.id, IDLDiagnostics(Vector(VerificationException(t.stacktraceString)))))
    }
  }

  private def runTyper(d: DomainMeshResolved): Either[LoadedDomain.TyperFailed, TypespaceImpl] = {
    (for {
      domain <- new IDLTyper(d).perform()
    } yield {
      new TypespaceImpl(domain)
    }).fold(issues => Left(LoadedDomain.TyperFailed(d.origin, d.id, issues)), Right.apply)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy