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

org.scalajs.linker.standard.SymbolRequirement.scala Maven / Gradle / Ivy

The newest version!
/*
 * Scala.js (https://www.scala-js.org/)
 *
 * Copyright EPFL.
 *
 * Licensed under Apache License 2.0
 * (https://www.apache.org/licenses/LICENSE-2.0).
 *
 * See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 */

package org.scalajs.linker.standard

import org.scalajs.ir.Names._

import org.scalajs.linker.interface.ModuleInitializer
import org.scalajs.linker.interface.unstable.ModuleInitializerImpl

sealed trait SymbolRequirement {
  final def ++(that: SymbolRequirement): SymbolRequirement =
    SymbolRequirement.multipleInternal(List(this, that))
}

object SymbolRequirement {
  import Nodes._

  def factory(originatingComponent: String): Factory =
    new Factory(originatingComponent)

  final class Factory private[SymbolRequirement] (origin: String) {
    def accessModule(moduleName: ClassName): SymbolRequirement =
      AccessModule(origin, moduleName)

    def callOnModule(moduleName: ClassName,
        methodName: MethodName): SymbolRequirement = {
      multiple(accessModule(moduleName), callMethod(moduleName, methodName))
    }

    def callOnModule(moduleName: ClassName,
        methodName: List[MethodName]): SymbolRequirement = {
      val methodCalls = methodName.map(callMethod(moduleName, _))
      multipleInternal(accessModule(moduleName) :: methodCalls)
    }

    def instantiateClass(className: ClassName,
        constructor: MethodName): SymbolRequirement = {
      InstantiateClass(origin, className, constructor)
    }

    def instantiateClass(className: ClassName,
        constructors: List[MethodName]): SymbolRequirement = {
      multipleInternal(constructors.map(instantiateClass(className, _)))
    }

    def instanceTests(className: ClassName): SymbolRequirement =
      InstanceTests(origin, className)

    def classData(className: ClassName): SymbolRequirement =
      ClassData(origin, className)

    def callMethod(className: ClassName,
        methodName: MethodName): SymbolRequirement = {
      CallMethod(origin, className, methodName, statically = false)
    }

    def callMethods(className: ClassName,
        methodNames: List[MethodName]): SymbolRequirement = {
      multipleInternal(methodNames.map(callMethod(className, _)))
    }

    def callMethodStatically(className: ClassName,
        methodName: MethodName): SymbolRequirement = {
      CallMethod(origin, className, methodName, statically = true)
    }

    def callStaticMethod(className: ClassName,
        methodName: MethodName): SymbolRequirement = {
      CallStaticMethod(origin, className, methodName)
    }

    @deprecated("broken (not actually optional), do not use", "1.13.2")
    def optional(requirement: SymbolRequirement): SymbolRequirement = requirement

    def multiple(requirements: SymbolRequirement*): SymbolRequirement =
      multipleInternal(requirements.toList)

    def none(): SymbolRequirement = NoRequirement
  }

  private def multipleInternal(requirements: List[SymbolRequirement]) = {
    val flattened = requirements.flatMap {
      case NoRequirement          => Nil
      case Multiple(requirements) => requirements
      case requirement            => requirement :: Nil
    }

    flattened match {
      case Nil      => NoRequirement
      case x :: Nil => x
      case xs       => Multiple(xs)
    }
  }

  private[linker] object Nodes {
    final case class AccessModule(origin: String, moduleName: ClassName)
        extends SymbolRequirement
    final case class InstantiateClass(origin: String, className: ClassName,
        constructor: MethodName)
        extends SymbolRequirement
    final case class InstanceTests(origin: String, className: ClassName)
        extends SymbolRequirement
    final case class ClassData(origin: String, className: ClassName)
        extends SymbolRequirement
    final case class CallMethod(origin: String, className: ClassName,
        methodName: MethodName, statically: Boolean)
        extends SymbolRequirement
    final case class CallStaticMethod(origin: String, className: ClassName,
        methodName: MethodName)
        extends SymbolRequirement
    final case class Multiple(requirements: List[SymbolRequirement])
        extends SymbolRequirement
    case object NoRequirement extends SymbolRequirement
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy