summaryrefslogtreecommitdiff
path: root/examples/scala-js/tools/shared/src/main/scala/scala/scalajs/tools/sem/Semantics.scala
blob: 9d17b06205e7840f36d3ae71264af5a03c9e739a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*                     __                                               *\
**     ________ ___   / /  ___      __ ____  Scala.js tools             **
**    / __/ __// _ | / /  / _ | __ / // __/  (c) 2014, LAMP/EPFL        **
**  __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \    http://scala-js.org/       **
** /____/\___/_/ |_/____/_/ | |__/ /____/                               **
**                          |/____/                                     **
\*                                                                      */


package scala.scalajs.tools.sem

import scala.collection.immutable.Traversable

final class Semantics private (
    val asInstanceOfs: CheckedBehavior,
    val strictFloats: Boolean) {

  import Semantics._

  def withAsInstanceOfs(behavior: CheckedBehavior): Semantics =
    copy(asInstanceOfs = behavior)

  def withStrictFloats(strictFloats: Boolean): Semantics =
    copy(strictFloats = strictFloats)

  def optimized: Semantics =
    copy(asInstanceOfs = this.asInstanceOfs.optimized)

  override def equals(that: Any): Boolean = that match {
    case that: Semantics =>
      this.asInstanceOfs == that.asInstanceOfs &&
      this.strictFloats  == that.strictFloats
    case _ =>
      false
  }

  override def hashCode(): Int = {
    import scala.util.hashing.MurmurHash3._
    var acc = HashSeed
    acc = mix(acc, asInstanceOfs.hashCode)
    acc = mixLast(acc, strictFloats.##)
    finalizeHash(acc, 1)
  }

  override def toString(): String = {
    s"""Semantics(
       |  asInstanceOfs = $asInstanceOfs,
       |  strictFloats  = $strictFloats
       |)""".stripMargin
  }

  /** Checks whether the given semantics setting is Java compliant */
  def isCompliant(name: String): Boolean = name match {
    case "asInstanceOfs" => asInstanceOfs == CheckedBehavior.Compliant
    case "strictFloats"  => strictFloats
    case _               => false
  }

  /** Retrieve a list of semantics which are set to compliant */
  def compliants: List[String] = {
    def cl(name: String, cond: Boolean) = if (cond) List(name) else Nil

    cl("asInstanceOfs", asInstanceOfs == CheckedBehavior.Compliant) ++
    cl("strictFloats",  strictFloats)
  }

  private def copy(
      asInstanceOfs: CheckedBehavior = this.asInstanceOfs,
      strictFloats: Boolean = this.strictFloats): Semantics = {
    new Semantics(
        asInstanceOfs = asInstanceOfs,
        strictFloats  = strictFloats)
  }
}

object Semantics {
  private val HashSeed =
    scala.util.hashing.MurmurHash3.stringHash(classOf[Semantics].getName)

  val Defaults: Semantics = new Semantics(
      asInstanceOfs = CheckedBehavior.Fatal,
      strictFloats  = false)

  def compliantTo(semantics: Traversable[String]): Semantics = {
    import Defaults._
    import CheckedBehavior._

    val semsSet = semantics.toSet

    def sw[T](name: String, compliant: T, default: T): T =
      if (semsSet.contains(name)) compliant else default

    new Semantics(
        asInstanceOfs = sw("asInstanceOfs", Compliant, asInstanceOfs),
        strictFloats  = sw("strictFloats",  true,      strictFloats))
  }
}