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

dotty.tools.backend.sjs.JSPrimitives.scala Maven / Gradle / Ivy

The newest version!
package dotty.tools.backend.sjs

import dotty.tools.dotc.core._
import Names.TermName
import StdNames._
import Types._
import Contexts._
import Symbols._

import dotty.tools.dotc.ast.tpd._
import dotty.tools.backend.jvm.DottyPrimitives

import scala.collection.mutable

object JSPrimitives {

  final val FirstJSPrimitiveCode = 300

  final val DYNNEW = FirstJSPrimitiveCode + 1 // Instantiate a new JavaScript object

  final val ARR_CREATE = DYNNEW + 1 // js.Array.apply (array literal syntax)

  final val TYPEOF = ARR_CREATE + 1 // typeof x
  final val JS_NATIVE = TYPEOF + 1  // js.native. Marker method. Fails if tried to be emitted.

  final val UNITVAL = JS_NATIVE + 1 // () value, which is undefined

  final val CONSTRUCTOROF = UNITVAL + 1                                // runtime.constructorOf(clazz)
  final val CREATE_INNER_JS_CLASS = CONSTRUCTOROF + 1                  // runtime.createInnerJSClass
  final val CREATE_LOCAL_JS_CLASS = CREATE_INNER_JS_CLASS + 1          // runtime.createLocalJSClass
  final val WITH_CONTEXTUAL_JS_CLASS_VALUE = CREATE_LOCAL_JS_CLASS + 1 // runtime.withContextualJSClassValue
  final val LINKING_INFO = WITH_CONTEXTUAL_JS_CLASS_VALUE + 1          // runtime.linkingInfo

  final val IN = LINKING_INFO + 1   // js.special.in
  final val INSTANCEOF = IN + 1     // js.special.instanceof
  final val DELETE = INSTANCEOF + 1 // js.special.delete
  final val FORIN = DELETE + 1      // js.special.forin
  final val DEBUGGER = FORIN + 1    // js.special.debugger

  final val THROW = DEBUGGER + 1

  final val LastJSPrimitiveCode = THROW

  def isJSPrimitive(code: Int): Boolean =
    code >= FirstJSPrimitiveCode && code <= LastJSPrimitiveCode

}

class JSPrimitives(ctx: Context) extends DottyPrimitives(ctx) {
  import JSPrimitives._
  import dotty.tools.backend.ScalaPrimitivesOps._

  private lazy val jsPrimitives: Map[Symbol, Int] = initJSPrimitives(ctx)

  override def getPrimitive(sym: Symbol): Int =
    jsPrimitives.getOrElse(sym, super.getPrimitive(sym))

  override def getPrimitive(app: Apply, tpe: Type)(implicit ctx: Context): Int =
    jsPrimitives.getOrElse(app.fun.symbol, super.getPrimitive(app, tpe))

  override def isPrimitive(fun: Tree): Boolean =
    jsPrimitives.contains(fun.symbol(ctx)) || super.isPrimitive(fun)

  /** Initialize the primitive map */
  private def initJSPrimitives(implicit ctx: Context): Map[Symbol, Int] = {

    val primitives = newMutableSymbolMap[Int]

    // !!! Code duplicate with DottyPrimitives
    /** Add a primitive operation to the map */
    def addPrimitive(s: Symbol, code: Int): Unit = {
      assert(!(primitives contains s), "Duplicate primitive " + s)
      primitives(s) = code
    }

    def addPrimitives(cls: Symbol, method: TermName, code: Int)(implicit ctx: Context): Unit = {
      val alts = cls.info.member(method).alternatives.map(_.symbol)
      if (alts.isEmpty) {
        ctx.error(s"Unknown primitive method $cls.$method")
      } else {
        for (s <- alts)
          addPrimitive(s, code)
      }
    }

    val jsdefn = JSDefinitions.jsdefn

    addPrimitive(jsdefn.JSDynamic_newInstance, DYNNEW)

    addPrimitive(jsdefn.JSArray_apply, ARR_CREATE)

    addPrimitive(jsdefn.JSPackage_typeOf, TYPEOF)
    addPrimitive(jsdefn.JSPackage_native, JS_NATIVE)

    addPrimitive(defn.BoxedUnit_UNIT, UNITVAL)

    addPrimitive(jsdefn.Runtime_constructorOf, CONSTRUCTOROF)
    /*addPrimitive(jsdefn.Runtime_createInnerJSClass, CREATE_INNER_JS_CLASS)
    addPrimitive(jsdefn.Runtime_createLocalJSClass, CREATE_LOCAL_JS_CLASS)
    addPrimitive(jsdefn.Runtime_withContextualJSClassValue, WITH_CONTEXTUAL_JS_CLASS_VALUE)*/
    addPrimitive(jsdefn.Runtime_linkingInfo, LINKING_INFO)

    addPrimitive(jsdefn.Special_in, IN)
    addPrimitive(jsdefn.Special_instanceof, INSTANCEOF)
    addPrimitive(jsdefn.Special_delete, DELETE)
    addPrimitive(jsdefn.Special_forin, FORIN)
    addPrimitive(jsdefn.Special_debugger, DEBUGGER)

    addPrimitive(defn.throwMethod, THROW)

    primitives.toMap
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy