Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.scalajs.linker.interface.Semantics.scala Maven / Gradle / Ivy
/*
* 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.interface
import CheckedBehavior._
import Fingerprint.FingerprintBuilder
final class Semantics private (
val asInstanceOfs: CheckedBehavior,
val arrayIndexOutOfBounds: CheckedBehavior,
val arrayStores: CheckedBehavior,
val negativeArraySizes: CheckedBehavior,
val nullPointers: CheckedBehavior,
val stringIndexOutOfBounds: CheckedBehavior,
val moduleInit: CheckedBehavior,
val strictFloats: Boolean,
val productionMode: Boolean,
val runtimeClassNameMapper: Semantics.RuntimeClassNameMapper) {
import Semantics._
def withAsInstanceOfs(behavior: CheckedBehavior): Semantics =
copy(asInstanceOfs = behavior)
def withArrayIndexOutOfBounds(behavior: CheckedBehavior): Semantics =
copy(arrayIndexOutOfBounds = behavior)
def withArrayStores(behavior: CheckedBehavior): Semantics =
copy(arrayStores = behavior)
def withNegativeArraySizes(behavior: CheckedBehavior): Semantics =
copy(negativeArraySizes = behavior)
def withNullPointers(behavior: CheckedBehavior): Semantics =
copy(nullPointers = behavior)
def withStringIndexOutOfBounds(behavior: CheckedBehavior): Semantics =
copy(stringIndexOutOfBounds = behavior)
def withModuleInit(moduleInit: CheckedBehavior): Semantics =
copy(moduleInit = moduleInit)
@deprecated(
"Scala.js now uses strict floats by default. " +
"Non-strict float semantics are deprecated and will eventually be " +
"removed.",
"1.9.0")
def withStrictFloats(strictFloats: Boolean): Semantics =
copy(strictFloats = strictFloats)
def withProductionMode(productionMode: Boolean): Semantics =
copy(productionMode = productionMode)
def withRuntimeClassNameMapper(
runtimeClassNameMapper: RuntimeClassNameMapper): Semantics = {
copy(runtimeClassNameMapper = runtimeClassNameMapper)
}
def optimized: Semantics = {
copy(asInstanceOfs = this.asInstanceOfs.optimized,
arrayIndexOutOfBounds = this.arrayIndexOutOfBounds.optimized,
arrayStores = this.arrayStores.optimized,
negativeArraySizes = this.negativeArraySizes.optimized,
nullPointers = this.nullPointers.optimized,
stringIndexOutOfBounds = this.stringIndexOutOfBounds.optimized,
moduleInit = this.moduleInit.optimized,
productionMode = true)
}
override def equals(that: Any): Boolean = that match {
case that: Semantics =>
this.asInstanceOfs == that.asInstanceOfs &&
this.arrayIndexOutOfBounds == that.arrayIndexOutOfBounds &&
this.arrayStores == that.arrayStores &&
this.negativeArraySizes == that.negativeArraySizes &&
this.nullPointers == that.nullPointers &&
this.stringIndexOutOfBounds == that.stringIndexOutOfBounds &&
this.moduleInit == that.moduleInit &&
this.strictFloats == that.strictFloats &&
this.productionMode == that.productionMode &&
this.runtimeClassNameMapper == that.runtimeClassNameMapper
case _ =>
false
}
override def hashCode(): Int = {
import scala.util.hashing.MurmurHash3._
var acc = HashSeed
acc = mix(acc, asInstanceOfs.##)
acc = mix(acc, arrayIndexOutOfBounds.##)
acc = mix(acc, arrayStores.##)
acc = mix(acc, negativeArraySizes.##)
acc = mix(acc, nullPointers.##)
acc = mix(acc, stringIndexOutOfBounds.##)
acc = mix(acc, moduleInit.##)
acc = mix(acc, strictFloats.##)
acc = mix(acc, productionMode.##)
acc = mixLast(acc, runtimeClassNameMapper.##)
finalizeHash(acc, 10)
}
override def toString(): String = {
s"""Semantics(
| asInstanceOfs = $asInstanceOfs,
| arrayIndexOutOfBounds = $arrayIndexOutOfBounds,
| arrayStores = $arrayStores,
| negativeArraySizes = $negativeArraySizes,
| nullPointers = $nullPointers,
| stringIndexOutOfBounds = $stringIndexOutOfBounds,
| moduleInit = $moduleInit,
| strictFloats = $strictFloats,
| productionMode = $productionMode
|)""".stripMargin
}
private def copy(
asInstanceOfs: CheckedBehavior = this.asInstanceOfs,
arrayIndexOutOfBounds: CheckedBehavior = this.arrayIndexOutOfBounds,
arrayStores: CheckedBehavior = this.arrayStores,
negativeArraySizes: CheckedBehavior = this.negativeArraySizes,
nullPointers: CheckedBehavior = this.nullPointers,
stringIndexOutOfBounds: CheckedBehavior = this.stringIndexOutOfBounds,
moduleInit: CheckedBehavior = this.moduleInit,
strictFloats: Boolean = this.strictFloats,
productionMode: Boolean = this.productionMode,
runtimeClassNameMapper: RuntimeClassNameMapper =
this.runtimeClassNameMapper): Semantics = {
new Semantics(
asInstanceOfs = asInstanceOfs,
arrayIndexOutOfBounds = arrayIndexOutOfBounds,
arrayStores = arrayStores,
negativeArraySizes = negativeArraySizes,
nullPointers = nullPointers,
stringIndexOutOfBounds = stringIndexOutOfBounds,
moduleInit = moduleInit,
strictFloats = strictFloats,
productionMode = productionMode,
runtimeClassNameMapper = runtimeClassNameMapper)
}
}
object Semantics {
private val HashSeed =
scala.util.hashing.MurmurHash3.stringHash(classOf[Semantics].getName)
sealed abstract class RuntimeClassNameMapper {
import RuntimeClassNameMapper._
def andThen(that: RuntimeClassNameMapper): RuntimeClassNameMapper =
AndThen(this, that)
private[interface] def apply(className: String): String = {
def rec(mapper: RuntimeClassNameMapper, className: String): String = {
mapper match {
case KeepAll =>
className
case DiscardAll =>
""
case mapper @ RegexReplace(_, _, replacement) =>
mapper.compiledPattern.matcher(className).replaceAll(replacement)
case AndThen(first, second) =>
rec(second, rec(first, className))
}
}
rec(this, className)
}
}
object RuntimeClassNameMapper {
private case object KeepAll extends RuntimeClassNameMapper
private case object DiscardAll extends RuntimeClassNameMapper
/* We use `pattern` and `flags` in the case parameters, rather than the
* `j.u.regex.Pattern`, because the latter does not have meaningful
* equality.
*/
private final case class RegexReplace(pattern: String, flags: Int,
replacement: String)(
val compiledPattern: java.util.regex.Pattern)
extends RuntimeClassNameMapper
private final case class AndThen(first: RuntimeClassNameMapper,
second: RuntimeClassNameMapper)
extends RuntimeClassNameMapper
def keepAll(): RuntimeClassNameMapper = KeepAll
def discardAll(): RuntimeClassNameMapper = DiscardAll
/** Returns a mapper that performs regular expression-based replacements.
*
* Given an input class name `className`, the mapper will return a new
* class name equivalent to
* {{{
* pattern.matcher(className).replaceAll(replacement)
* }}}
*/
def regexReplace(pattern: java.util.regex.Pattern,
replacement: String): RuntimeClassNameMapper = {
RegexReplace(pattern.pattern(), pattern.flags(), replacement)(pattern)
}
/** Returns a mapper that performs regular expression-based replacements.
*
* Given an input class name `className`, the mapper will return a new
* class name equivalent to
* {{{
* regex.replaceAllIn(className, replacement)
* }}}
*/
def regexReplace(regex: scala.util.matching.Regex,
replacement: String): RuntimeClassNameMapper = {
regexReplace(regex.pattern, replacement)
}
private[interface] implicit object RuntimeClassNameMapperFingerprint
extends Fingerprint[RuntimeClassNameMapper] {
override def fingerprint(mapper: RuntimeClassNameMapper): String = {
mapper match {
case KeepAll => "KeepAll"
case DiscardAll => "DiscardAll"
case RegexReplace(pattern, flags, replacement) =>
new FingerprintBuilder("RegexReplace")
.addField("pattern", pattern)
.addField("flags", flags)
.addField("replacement", replacement)
.build()
case AndThen(first, second) =>
new FingerprintBuilder("AndThen")
.addField("first", fingerprint(first))
.addField("second", fingerprint(second))
.build()
}
}
}
}
private[interface] implicit object SemanticsFingerprint
extends Fingerprint[Semantics] {
override def fingerprint(semantics: Semantics): String = {
new FingerprintBuilder("Semantics")
.addField("asInstanceOfs", semantics.asInstanceOfs)
.addField("arrayIndexOutOfBounds", semantics.arrayIndexOutOfBounds)
.addField("arrayStores", semantics.arrayStores)
.addField("negativeArraySizes", semantics.negativeArraySizes)
.addField("nullPointers", semantics.nullPointers)
.addField("stringIndexOutOfBounds", semantics.stringIndexOutOfBounds)
.addField("moduleInit", semantics.moduleInit)
.addField("strictFloats", semantics.strictFloats)
.addField("productionMode", semantics.productionMode)
.addField("runtimeClassNameMapper", semantics.runtimeClassNameMapper)
.build()
}
}
val Defaults: Semantics = new Semantics(
asInstanceOfs = Fatal,
arrayIndexOutOfBounds = Fatal,
arrayStores = Fatal,
negativeArraySizes = Fatal,
nullPointers = Fatal,
stringIndexOutOfBounds = Fatal,
moduleInit = Unchecked,
strictFloats = true,
productionMode = false,
runtimeClassNameMapper = RuntimeClassNameMapper.keepAll())
}