summaryrefslogtreecommitdiff
path: root/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer')
-rw-r--r--examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstBuilder.scala47
-rw-r--r--examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstTransformer.scala397
-rw-r--r--examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala74
-rw-r--r--examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/LoggerErrorManager.scala38
-rw-r--r--examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ParIncOptimizer.scala188
-rw-r--r--examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala216
6 files changed, 0 insertions, 960 deletions
diff --git a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstBuilder.scala b/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstBuilder.scala
deleted file mode 100644
index 8d2eb2b..0000000
--- a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstBuilder.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-package scala.scalajs.tools.optimizer
-
-import scala.scalajs.ir
-import ir.Position.NoPosition
-
-import scala.scalajs.tools.javascript.Trees.Tree
-
-import com.google.javascript.rhino._
-import com.google.javascript.rhino.jstype.{StaticSourceFile, SimpleSourceFile}
-import com.google.javascript.jscomp._
-
-import scala.collection.mutable
-
-import java.net.URI
-
-class ClosureAstBuilder(
- relativizeBaseURI: Option[URI] = None) extends JSTreeBuilder {
-
- private val transformer = new ClosureAstTransformer(relativizeBaseURI)
- private val treeBuf = mutable.ListBuffer.empty[Node]
-
- def addJSTree(tree: Tree): Unit =
- treeBuf += transformer.transformStat(tree)(NoPosition)
-
- lazy val closureAST: SourceAst = {
- val root = transformer.setNodePosition(IR.script(treeBuf: _*), NoPosition)
-
- treeBuf.clear()
-
- new ClosureAstBuilder.ScalaJSSourceAst(root)
- }
-
-}
-
-object ClosureAstBuilder {
- // Dummy Source AST class
-
- class ScalaJSSourceAst(root: Node) extends SourceAst {
- def getAstRoot(compiler: AbstractCompiler): Node = root
- def clearAst(): Unit = () // Just for GC. Nonsensical here.
- def getInputId(): InputId = root.getInputId()
- def getSourceFile(): SourceFile =
- root.getStaticSourceFile().asInstanceOf[SourceFile]
- def setSourceFile(file: SourceFile): Unit =
- if (getSourceFile() ne file) throw new IllegalStateException
- }
-}
diff --git a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstTransformer.scala b/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstTransformer.scala
deleted file mode 100644
index af22501..0000000
--- a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ClosureAstTransformer.scala
+++ /dev/null
@@ -1,397 +0,0 @@
-package scala.scalajs.tools.optimizer
-
-import scala.scalajs.ir
-import ir.Position
-import ir.Position.NoPosition
-
-import scala.scalajs.tools.javascript.Trees._
-
-import com.google.javascript.rhino._
-import com.google.javascript.jscomp._
-
-import scala.collection.mutable
-import scala.annotation.tailrec
-
-import java.net.URI
-
-class ClosureAstTransformer(val relativizeBaseURI: Option[URI] = None) {
-
- private val inputId = new InputId("Scala.js IR")
-
- private val dummySourceName = new java.net.URI("virtualfile:scala.js-ir")
-
- def transformStat(tree: Tree)(implicit parentPos: Position): Node =
- innerTransformStat(tree, tree.pos orElse parentPos)
-
- private def innerTransformStat(tree: Tree, pos_in: Position): Node = {
- implicit val pos = pos_in
-
- wrapTransform(tree) {
- case VarDef(ident, _, EmptyTree) =>
- new Node(Token.VAR, transformName(ident))
- case VarDef(ident, _, rhs) =>
- val node = transformName(ident)
- node.addChildToFront(transformExpr(rhs))
- new Node(Token.VAR, node)
- case Skip() =>
- new Node(Token.EMPTY)
- case Block(stats) =>
- transformBlock(stats, pos)
- case Labeled(label, body) =>
- new Node(Token.LABEL, transformLabel(label), transformBlock(body))
- case Return(EmptyTree) =>
- new Node(Token.RETURN)
- case Return(expr) =>
- new Node(Token.RETURN, transformExpr(expr))
- case If(cond, thenp, Skip()) =>
- new Node(Token.IF, transformExpr(cond), transformBlock(thenp))
- case If(cond, thenp, elsep) =>
- new Node(Token.IF, transformExpr(cond),
- transformBlock(thenp), transformBlock(elsep))
- case While(cond, body, None) =>
- new Node(Token.WHILE, transformExpr(cond), transformBlock(body))
- case While(cond, body, Some(label)) =>
- val whileNode =
- new Node(Token.WHILE, transformExpr(cond), transformBlock(body))
- new Node(Token.LABEL, transformLabel(label),
- setNodePosition(whileNode, pos))
- case DoWhile(body, cond, None) =>
- new Node(Token.DO, transformBlock(body), transformExpr(cond))
- case DoWhile(body, cond, Some(label)) =>
- val doNode =
- new Node(Token.DO, transformBlock(body), transformExpr(cond))
- new Node(Token.LABEL, transformLabel(label),
- setNodePosition(doNode, pos))
- case Try(block, errVar, handler, EmptyTree) =>
- val catchPos = handler.pos orElse pos
- val catchNode =
- new Node(Token.CATCH, transformName(errVar), transformBlock(handler))
- val blockNode =
- new Node(Token.BLOCK, setNodePosition(catchNode, catchPos))
- new Node(Token.TRY, transformBlock(block),
- setNodePosition(blockNode, catchPos))
- case Try(block, _, EmptyTree, finalizer) =>
- val blockNode = setNodePosition(new Node(Token.BLOCK), pos)
- new Node(Token.TRY, transformBlock(block), blockNode,
- transformBlock(finalizer))
- case Try(block, errVar, handler, finalizer) =>
- val catchPos = handler.pos orElse pos
- val catchNode =
- new Node(Token.CATCH, transformName(errVar), transformBlock(handler))
- val blockNode =
- new Node(Token.BLOCK, setNodePosition(catchNode, catchPos))
- new Node(Token.TRY, transformBlock(block),
- setNodePosition(blockNode, catchPos), transformBlock(finalizer))
- case Throw(expr) =>
- new Node(Token.THROW, transformExpr(expr))
- case Break(None) =>
- new Node(Token.BREAK)
- case Break(Some(label)) =>
- new Node(Token.BREAK, transformLabel(label))
- case Continue(None) =>
- new Node(Token.CONTINUE)
- case Continue(Some(label)) =>
- new Node(Token.CONTINUE, transformLabel(label))
-
- case Switch(selector, cases, default) =>
- val switchNode = new Node(Token.SWITCH, transformExpr(selector))
-
- for ((expr, body) <- cases) {
- val bodyNode = transformBlock(body)
- bodyNode.putBooleanProp(Node.SYNTHETIC_BLOCK_PROP, true)
- val caseNode = new Node(Token.CASE, transformExpr(expr), bodyNode)
- switchNode.addChildToBack(
- setNodePosition(caseNode, expr.pos orElse pos))
- }
-
- if (default != EmptyTree) {
- val bodyNode = transformBlock(default)
- bodyNode.putBooleanProp(Node.SYNTHETIC_BLOCK_PROP, true)
- val caseNode = new Node(Token.DEFAULT_CASE, bodyNode)
- switchNode.addChildToBack(
- setNodePosition(caseNode, default.pos orElse pos))
- }
-
- switchNode
-
- case Debugger() =>
- new Node(Token.DEBUGGER)
- case _ =>
- // We just assume it is an expression
- new Node(Token.EXPR_RESULT, transformExpr(tree))
- }
- }
-
- def transformExpr(tree: Tree)(implicit parentPos: Position): Node =
- innerTransformExpr(tree, tree.pos orElse parentPos)
-
- private def innerTransformExpr(tree: Tree, pos_in: Position): Node = {
- implicit val pos = pos_in
-
- wrapTransform(tree) {
- case Block(exprs) =>
- exprs.map(transformExpr).reduceRight { (expr1, expr2) =>
- setNodePosition(new Node(Token.COMMA, expr1, expr2), pos)
- }
- case If(cond, thenp, elsep) =>
- new Node(Token.HOOK, transformExpr(cond),
- transformExpr(thenp), transformExpr(elsep))
- case Assign(lhs, rhs) =>
- new Node(Token.ASSIGN, transformExpr(lhs), transformExpr(rhs))
- case New(ctor, args) =>
- val node = new Node(Token.NEW, transformExpr(ctor))
- args.foreach(arg => node.addChildToBack(transformExpr(arg)))
- node
- case DotSelect(qualifier, item) =>
- new Node(Token.GETPROP, transformExpr(qualifier), transformString(item))
- case BracketSelect(qualifier, item) =>
- new Node(Token.GETELEM, transformExpr(qualifier), transformExpr(item))
-
- case Apply(fun, args) =>
- val node = new Node(Token.CALL, transformExpr(fun))
- args.foreach(arg => node.addChildToBack(transformExpr(arg)))
-
- // Closure needs to know (from the parser), if the call has a bound
- // `this` or not. Since JSDesugar inserts protects calls if necessary,
- // it is sufficient to check if we have a select as target
- if (!fun.isInstanceOf[DotSelect] &&
- !fun.isInstanceOf[BracketSelect])
- node.putBooleanProp(Node.FREE_CALL, true)
-
- node
-
- case Delete(prop) =>
- new Node(Token.DELPROP, transformExpr(prop))
- case UnaryOp(op, lhs) =>
- mkUnaryOp(op, transformExpr(lhs))
- case BinaryOp(op, lhs, rhs) =>
- mkBinaryOp(op, transformExpr(lhs), transformExpr(rhs))
- case ArrayConstr(items) =>
- val node = new Node(Token.ARRAYLIT)
- items.foreach(i => node.addChildToBack(transformExpr(i)))
- node
-
- case ObjectConstr(fields) =>
- val node = new Node(Token.OBJECTLIT)
-
- for ((name, expr) <- fields) {
- val fldNode = transformStringKey(name)
- fldNode.addChildToBack(transformExpr(expr))
- node.addChildToBack(fldNode)
- }
-
- node
-
- case Undefined() =>
- new Node(Token.VOID, setNodePosition(Node.newNumber(0.0), pos))
- case Null() =>
- new Node(Token.NULL)
- case BooleanLiteral(value) =>
- if (value) new Node(Token.TRUE) else new Node(Token.FALSE)
- case IntLiteral(value) =>
- Node.newNumber(value)
- case DoubleLiteral(value) =>
- Node.newNumber(value)
- case StringLiteral(value) =>
- Node.newString(value)
- case VarRef(ident, _) =>
- transformName(ident)
- case This() =>
- new Node(Token.THIS)
-
- case Function(args, body) =>
- // Note that a Function may also be a statement (when it is named),
- // but Scala.js does not have such an IR node
- val paramList = new Node(Token.PARAM_LIST)
- args.foreach(arg => paramList.addChildToBack(transformParam(arg)))
-
- val emptyName = setNodePosition(Node.newString(Token.NAME, ""), pos)
-
- new Node(Token.FUNCTION, emptyName, paramList, transformBlock(body))
-
- case _ =>
- throw new TransformException(s"Unknown tree of class ${tree.getClass()}")
- }
- }
-
- def transformParam(param: ParamDef)(implicit parentPos: Position): Node =
- transformName(param.name)
-
- def transformName(ident: Ident)(implicit parentPos: Position): Node =
- setNodePosition(Node.newString(Token.NAME, ident.name),
- ident.pos orElse parentPos)
-
- def transformLabel(ident: Ident)(implicit parentPos: Position): Node =
- setNodePosition(Node.newString(Token.LABEL_NAME, ident.name),
- ident.pos orElse parentPos)
-
- def transformString(pName: PropertyName)(implicit parentPos: Position): Node =
- setNodePosition(Node.newString(pName.name), pName.pos orElse parentPos)
-
- def transformStringKey(pName: PropertyName)(
- implicit parentPos: Position): Node = {
- val node = Node.newString(Token.STRING_KEY, pName.name)
-
- if (pName.isInstanceOf[StringLiteral])
- node.setQuotedString()
-
- setNodePosition(node, pName.pos orElse parentPos)
- }
-
- def transformBlock(tree: Tree)(implicit parentPos: Position): Node = {
- val pos = if (tree.pos.isDefined) tree.pos else parentPos
- wrapTransform(tree) {
- case Block(stats) =>
- transformBlock(stats, pos)
- case tree =>
- transformBlock(List(tree), pos)
- } (pos)
- }
-
- def transformBlock(stats: List[Tree], blockPos: Position): Node = {
- @inline def ctorDoc(node: Node) = {
- val b = new JSDocInfoBuilder(false)
- b.recordConstructor()
- b.build(node)
- }
-
- val block = new Node(Token.BLOCK)
-
- // The Rhino IR attaches DocComments to the following nodes (rather than
- // having individual nodes). We preprocess these here.
- @tailrec
- def loop(ts: List[Tree], nextIsCtor: Boolean = false): Unit = ts match {
- case DocComment(text) :: tss if text.startsWith("@constructor") =>
- loop(tss, nextIsCtor = true)
- case DocComment(text) :: tss =>
- loop(tss)
- case t :: tss =>
- val node = transformStat(t)(blockPos)
- if (nextIsCtor) {
- // The @constructor must be propagated through an ExprResult node
- val trg =
- if (node.isExprResult()) node.getChildAtIndex(0)
- else node
-
- trg.setJSDocInfo(ctorDoc(trg))
- }
-
- block.addChildToBack(node)
-
- loop(tss)
- case Nil =>
- }
-
- loop(stats)
-
- block
- }
-
- @inline
- private def wrapTransform(tree: Tree)(body: Tree => Node)(
- implicit pos: Position): Node = {
- try {
- setNodePosition(body(tree), pos)
- } catch {
- case e: TransformException =>
- throw e // pass through
- case e: RuntimeException =>
- throw new TransformException(tree, e)
- }
- }
-
- def setNodePosition(node: Node, pos: ir.Position): node.type = {
- if (pos != ir.Position.NoPosition) {
- attachSourceFile(node, pos.source)
- node.setLineno(pos.line+1)
- node.setCharno(pos.column)
- } else {
- attachSourceFile(node, dummySourceName)
- }
- node
- }
-
- private def attachSourceFile(node: Node, source: URI): node.type = {
- val str = sourceUriToString(source)
-
- node.setInputId(inputId)
- node.setStaticSourceFile(new SourceFile(str))
-
- node
- }
-
- private def sourceUriToString(uri: URI): String = {
- val relURI = relativizeBaseURI.fold(uri)(ir.Utils.relativize(_, uri))
- ir.Utils.fixFileURI(relURI).toASCIIString
- }
-
- // Helpers for IR
- @inline
- private def mkUnaryOp(op: String, lhs: Node): Node = {
- val tok = op match {
- case "!" => Token.NOT
- case "~" => Token.BITNOT
- case "+" => Token.POS
- case "-" => Token.NEG
- case "typeof" => Token.TYPEOF
- case _ => throw new TransformException(s"Unhandled unary op: $op")
- }
-
- new Node(tok, lhs)
- }
-
- @inline
- private def mkBinaryOp(op: String, lhs: Node, rhs: Node): Node = {
- val tok = op match {
- case "|" => Token.BITOR
- case "&" => Token.BITAND
- case "^" => Token.BITXOR
- case "==" => Token.EQ
- case "!=" => Token.NE
- case "<" => Token.LT
- case "<=" => Token.LE
- case ">" => Token.GT
- case ">=" => Token.GE
- case "<<" => Token.LSH
- case ">>" => Token.RSH
- case ">>>" => Token.URSH
- case "+" => Token.ADD
- case "-" => Token.SUB
- case "*" => Token.MUL
- case "/" => Token.DIV
- case "%" => Token.MOD
- case "===" => Token.SHEQ
- case "!==" => Token.SHNE
- case "in" => Token.IN
- case "instanceof" => Token.INSTANCEOF
- case "||" => Token.OR
- case "&&" => Token.AND
- case _ =>
- throw new TransformException(s"Unhandled binary op: $op")
- }
-
- new Node(tok, lhs, rhs)
- }
-
- // Exception wrapper in transforms
-
- class TransformException private (msg: String, e: Throwable)
- extends RuntimeException(msg, e) {
-
- def this(tree: Tree, e: Throwable) =
- this(TransformException.mkMsg(tree), e)
-
- def this(msg: String) = this(msg, null)
- }
-
- object TransformException {
- import ir.Printers._
- import java.io._
-
- private def mkMsg(tree: Tree): String = {
- "Exception while translating Scala.js JS tree to GCC IR at tree:\n" +
- tree.show
- }
- }
-
-}
diff --git a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala b/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala
deleted file mode 100644
index 471ed65..0000000
--- a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ __ ____ Scala.js tools **
-** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
-** /____/\___/_/ |_/____/_/ | |__/ /____/ **
-** |/____/ **
-\* */
-
-
-package scala.scalajs.tools.optimizer
-
-import scala.annotation.tailrec
-
-import scala.collection.concurrent.TrieMap
-
-import java.util.concurrent.atomic._
-
-private[optimizer] object ConcurrencyUtils {
-
- /** An atomic accumulator supports adding single elements and retrieving and
- * deleting all contained elements */
- type AtomicAcc[T] = AtomicReference[List[T]]
-
- object AtomicAcc {
- @inline final def empty[T]: AtomicAcc[T] =
- new AtomicReference[List[T]](Nil)
- @inline final def apply[T](l: List[T]): AtomicAcc[T] =
- new AtomicReference(l)
- }
-
- implicit class AtomicAccOps[T](val acc: AtomicAcc[T]) extends AnyVal {
- @inline final def size: Int = acc.get.size
-
- @inline
- final def +=(x: T): Unit = AtomicAccOps.append(acc, x)
-
- @inline
- final def removeAll(): List[T] = AtomicAccOps.removeAll(acc)
- }
-
- object AtomicAccOps {
- @inline
- @tailrec
- private final def append[T](acc: AtomicAcc[T], x: T): Boolean = {
- val oldV = acc.get
- val newV = x :: oldV
- acc.compareAndSet(oldV, newV) || append(acc, x)
- }
-
- @inline
- private final def removeAll[T](acc: AtomicAcc[T]): List[T] =
- acc.getAndSet(Nil)
- }
-
- type TrieSet[T] = TrieMap[T, Null]
-
- implicit class TrieSetOps[T](val set: TrieSet[T]) extends AnyVal {
- @inline final def +=(x: T): Unit = set.put(x, null)
- }
-
- object TrieSet {
- @inline final def empty[T]: TrieSet[T] = TrieMap.empty
- }
-
- implicit class TrieMapOps[K,V](val map: TrieMap[K,V]) extends AnyVal {
- @inline final def getOrPut(k: K, default: => V): V = {
- map.get(k).getOrElse {
- val v = default
- map.putIfAbsent(k, v).getOrElse(v)
- }
- }
- }
-
-}
diff --git a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/LoggerErrorManager.scala b/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/LoggerErrorManager.scala
deleted file mode 100644
index d51dd7b..0000000
--- a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/LoggerErrorManager.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-package scala.scalajs.tools.optimizer
-
-import com.google.javascript.jscomp.{ BasicErrorManager, CheckLevel, JSError }
-
-import scala.scalajs.tools.logging.Logger
-
-/** A Google Closure Error Manager that forwards to a tools.logging.Logger */
-class LoggerErrorManager(private val log: Logger) extends BasicErrorManager {
-
- /** Ugly hack to disable FRACTIONAL_BITWISE_OPERAND warnings. Since its
- * DiagnosticType (PeepholeFoldConstants.FRACTIONAL_BITWISE_OPERAND) is
- * package private.
- */
- override def report(level: CheckLevel, error: JSError): Unit = {
- if (error.getType.key == "JSC_FRACTIONAL_BITWISE_OPERAND")
- super.report(CheckLevel.OFF, error)
- else
- super.report(level, error)
- }
-
- def println(level: CheckLevel, error: JSError): Unit = level match {
- case CheckLevel.WARNING => log.warn (s"Closure: ${error}")
- case CheckLevel.ERROR => log.error(s"Closure: ${error}")
- case CheckLevel.OFF =>
- }
-
- protected def printSummary(): Unit = {
- val msg = s"Closure: ${getErrorCount} error(s), ${getWarningCount} warning(s)"
-
- if (getErrorCount > 0)
- log.error(msg)
- else if (getWarningCount > 0)
- log.warn(msg)
- else
- log.info(msg)
- }
-
-}
diff --git a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ParIncOptimizer.scala b/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ParIncOptimizer.scala
deleted file mode 100644
index 422238e..0000000
--- a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ParIncOptimizer.scala
+++ /dev/null
@@ -1,188 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ __ ____ Scala.js tools **
-** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
-** /____/\___/_/ |_/____/_/ | |__/ /____/ **
-** |/____/ **
-\* */
-
-
-package scala.scalajs.tools.optimizer
-
-import scala.collection.{GenTraversableOnce, GenIterable}
-import scala.collection.concurrent.TrieMap
-import scala.collection.parallel.mutable.{ParTrieMap, ParArray}
-
-import java.util.concurrent.atomic._
-
-import scala.scalajs.tools.sem.Semantics
-
-import ConcurrencyUtils._
-
-class ParIncOptimizer(semantics: Semantics) extends GenIncOptimizer(semantics) {
-
- protected object CollOps extends GenIncOptimizer.AbsCollOps {
- type Map[K, V] = TrieMap[K, V]
- type ParMap[K, V] = ParTrieMap[K, V]
- type AccMap[K, V] = TrieMap[K, AtomicAcc[V]]
- type ParIterable[V] = ParArray[V]
- type Addable[V] = AtomicAcc[V]
-
- def emptyAccMap[K, V]: AccMap[K, V] = TrieMap.empty
- def emptyMap[K, V]: Map[K, V] = TrieMap.empty
- def emptyParMap[K, V]: ParMap[K, V] = ParTrieMap.empty
- def emptyParIterable[V]: ParIterable[V] = ParArray.empty
-
- // Operations on ParMap
- def put[K, V](map: ParMap[K, V], k: K, v: V): Unit = map.put(k, v)
- def remove[K, V](map: ParMap[K, V], k: K): Option[V] = map.remove(k)
-
- def retain[K, V](map: ParMap[K, V])(p: (K, V) => Boolean): Unit = {
- map.foreach { case (k, v) =>
- if (!p(k, v))
- map.remove(k)
- }
- }
-
- // Operations on AccMap
- def acc[K, V](map: AccMap[K, V], k: K, v: V): Unit =
- map.getOrPut(k, AtomicAcc.empty) += v
-
- def getAcc[K, V](map: AccMap[K, V], k: K): GenIterable[V] =
- map.get(k).fold[Iterable[V]](Nil)(_.removeAll()).toParArray
-
- def parFlatMapKeys[A, B](map: AccMap[A, _])(
- f: A => GenTraversableOnce[B]): GenIterable[B] =
- map.keys.flatMap(f).toParArray
-
- // Operations on ParIterable
- def prepAdd[V](it: ParIterable[V]): Addable[V] =
- AtomicAcc(it.toList)
-
- def add[V](addable: Addable[V], v: V): Unit =
- addable += v
-
- def finishAdd[V](addable: Addable[V]): ParIterable[V] =
- addable.removeAll().toParArray
- }
-
- private val _interfaces = TrieMap.empty[String, InterfaceType]
- protected def getInterface(encodedName: String): InterfaceType =
- _interfaces.getOrPut(encodedName, new ParInterfaceType(encodedName))
-
- private val methodsToProcess: AtomicAcc[MethodImpl] = AtomicAcc.empty
- protected def scheduleMethod(method: MethodImpl): Unit =
- methodsToProcess += method
-
- protected def newMethodImpl(owner: MethodContainer,
- encodedName: String): MethodImpl = new ParMethodImpl(owner, encodedName)
-
- protected def processAllTaggedMethods(): Unit = {
- val methods = methodsToProcess.removeAll().toParArray
- logProcessingMethods(methods.count(!_.deleted))
- for (method <- methods)
- method.process()
- }
-
- private class ParInterfaceType(encName: String) extends InterfaceType(encName) {
- private val ancestorsAskers = TrieSet.empty[MethodImpl]
- private val dynamicCallers = TrieMap.empty[String, TrieSet[MethodImpl]]
- private val staticCallers = TrieMap.empty[String, TrieSet[MethodImpl]]
-
- private var _ancestors: List[String] = encodedName :: Nil
-
- private val _instantiatedSubclasses: TrieSet[Class] = TrieSet.empty
-
- /** PROCESS PASS ONLY. Concurrency safe except with
- * [[addInstantiatedSubclass]] and [[removeInstantiatedSubclass]]
- */
- def instantiatedSubclasses: Iterable[Class] =
- _instantiatedSubclasses.keys
-
- /** UPDATE PASS ONLY. Concurrency safe except with
- * [[instantiatedSubclasses]]
- */
- def addInstantiatedSubclass(x: Class): Unit =
- _instantiatedSubclasses += x
-
- /** UPDATE PASS ONLY. Concurrency safe except with
- * [[instantiatedSubclasses]]
- */
- def removeInstantiatedSubclass(x: Class): Unit =
- _instantiatedSubclasses -= x
-
- /** PROCESS PASS ONLY. Concurrency safe except with [[ancestors_=]] */
- def ancestors: List[String] = _ancestors
-
- /** UPDATE PASS ONLY. Not concurrency safe. */
- def ancestors_=(v: List[String]): Unit = {
- if (v != _ancestors) {
- _ancestors = v
- ancestorsAskers.keysIterator.foreach(_.tag())
- ancestorsAskers.clear()
- }
- }
-
- /** PROCESS PASS ONLY. Concurrency safe except with [[ancestors_=]]. */
- def registerAskAncestors(asker: MethodImpl): Unit =
- ancestorsAskers += asker
-
- /** PROCESS PASS ONLY. */
- def registerDynamicCaller(methodName: String, caller: MethodImpl): Unit =
- dynamicCallers.getOrPut(methodName, TrieSet.empty) += caller
-
- /** PROCESS PASS ONLY. */
- def registerStaticCaller(methodName: String, caller: MethodImpl): Unit =
- staticCallers.getOrPut(methodName, TrieSet.empty) += caller
-
- /** UPDATE PASS ONLY. */
- def unregisterDependee(dependee: MethodImpl): Unit = {
- ancestorsAskers -= dependee
- dynamicCallers.valuesIterator.foreach(_ -= dependee)
- staticCallers.valuesIterator.foreach(_ -= dependee)
- }
-
- /** UPDATE PASS ONLY. */
- def tagDynamicCallersOf(methodName: String): Unit =
- dynamicCallers.remove(methodName).foreach(_.keysIterator.foreach(_.tag()))
-
- /** UPDATE PASS ONLY. */
- def tagStaticCallersOf(methodName: String): Unit =
- staticCallers.remove(methodName).foreach(_.keysIterator.foreach(_.tag()))
- }
-
- private class ParMethodImpl(owner: MethodContainer,
- encodedName: String) extends MethodImpl(owner, encodedName) {
-
- private val bodyAskers = TrieSet.empty[MethodImpl]
-
- /** PROCESS PASS ONLY. */
- def registerBodyAsker(asker: MethodImpl): Unit =
- bodyAskers += asker
-
- /** UPDATE PASS ONLY. */
- def unregisterDependee(dependee: MethodImpl): Unit =
- bodyAskers -= dependee
-
- /** UPDATE PASS ONLY. */
- def tagBodyAskers(): Unit = {
- bodyAskers.keysIterator.foreach(_.tag())
- bodyAskers.clear()
- }
-
- private val _registeredTo = AtomicAcc.empty[Unregisterable]
- private val tagged = new AtomicBoolean(false)
-
- protected def registeredTo(intf: Unregisterable): Unit =
- _registeredTo += intf
-
- protected def unregisterFromEverywhere(): Unit = {
- _registeredTo.removeAll().foreach(_.unregisterDependee(this))
- }
-
- protected def protectTag(): Boolean = !tagged.getAndSet(true)
- protected def resetTag(): Unit = tagged.set(false)
-
- }
-
-}
diff --git a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala b/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala
deleted file mode 100644
index 146b2b8..0000000
--- a/examples/scala-js/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ScalaJSClosureOptimizer.scala
+++ /dev/null
@@ -1,216 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ __ ____ Scala.js tools **
-** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
-** /____/\___/_/ |_/____/_/ | |__/ /____/ **
-** |/____/ **
-\* */
-
-
-package scala.scalajs.tools.optimizer
-
-import scala.scalajs.tools.sem.Semantics
-import scala.scalajs.tools.classpath._
-import scala.scalajs.tools.logging._
-import scala.scalajs.tools.io._
-import scala.scalajs.tools.corelib.CoreJSLibs
-
-import com.google.javascript.jscomp.{
- SourceFile => ClosureSource,
- Compiler => ClosureCompiler,
- CompilerOptions => ClosureOptions,
- _
-}
-import scala.collection.JavaConverters._
-import scala.collection.immutable.{Seq, Traversable}
-
-import java.net.URI
-
-/** Scala.js Closure optimizer: does advanced optimizations with Closure. */
-class ScalaJSClosureOptimizer(semantics: Semantics) {
- import ScalaJSClosureOptimizer._
-
- private def toClosureSource(file: VirtualJSFile) =
- ClosureSource.fromReader(file.toURI.toString(), file.reader)
-
- private def toClosureInput(file: VirtualJSFile) =
- new CompilerInput(toClosureSource(file))
-
- /** Fully optimizes an [[IRClasspath]] by asking the ScalaJSOptimizer to
- * emit a closure AST and then compiling this AST directly
- */
- def optimizeCP(optimizer: ScalaJSOptimizer,
- inputs: Inputs[ScalaJSOptimizer.Inputs[IRClasspath]],
- outCfg: OutputConfig, logger: Logger): LinkedClasspath = {
-
- val cp = inputs.input.input
-
- CacheUtils.cached(cp.version, outCfg.output, outCfg.cache) {
- logger.info(s"Full Optimizing ${outCfg.output.path}")
-
- val irFastOptInput =
- inputs.input.copy(input = inputs.input.input.scalaJSIR)
- val irFullOptInput = inputs.copy(input = irFastOptInput)
-
- optimizeIR(optimizer, irFullOptInput, outCfg, logger)
- }
-
- new LinkedClasspath(cp.jsLibs, outCfg.output, cp.requiresDOM, cp.version)
- }
-
- def optimizeIR(optimizer: ScalaJSOptimizer,
- inputs: Inputs[ScalaJSOptimizer.Inputs[Traversable[VirtualScalaJSIRFile]]],
- outCfg: OutputConfig, logger: Logger): Unit = {
-
- // Build Closure IR via ScalaJSOptimizer
- val builder = new ClosureAstBuilder(outCfg.relativizeSourceMapBase)
-
- optimizer.optimizeIR(inputs.input, outCfg, builder, logger)
-
- // Build a Closure JSModule which includes the core libs
- val module = new JSModule("Scala.js")
-
- for (lib <- CoreJSLibs.libs(semantics))
- module.add(toClosureInput(lib))
-
- val ast = builder.closureAST
- module.add(new CompilerInput(ast, ast.getInputId(), false))
-
- for (export <- inputs.additionalExports)
- module.add(toClosureInput(export))
-
- // Compile the module
- val closureExterns =
- (ScalaJSExternsFile +: inputs.additionalExterns).map(toClosureSource)
-
- val options = closureOptions(outCfg)
- val compiler = closureCompiler(logger)
-
- val result = GenIncOptimizer.logTime(logger, "Closure Compiler pass") {
- compiler.compileModules(
- closureExterns.asJava, List(module).asJava, options)
- }
-
- GenIncOptimizer.logTime(logger, "Write Closure result") {
- writeResult(result, compiler, outCfg.output)
- }
- }
-
- private def writeResult(result: Result, compiler: ClosureCompiler,
- output: WritableVirtualJSFile): Unit = {
-
- val outputContent = if (result.errors.nonEmpty) ""
- else "(function(){'use strict';" + compiler.toSource + "}).call(this);\n"
-
- val sourceMap = Option(compiler.getSourceMap())
-
- // Write optimized code
- val w = output.contentWriter
- try {
- w.write(outputContent)
- if (sourceMap.isDefined)
- w.write("//# sourceMappingURL=" + output.name + ".map\n")
- } finally w.close()
-
- // Write source map (if available)
- sourceMap.foreach { sm =>
- val w = output.sourceMapWriter
- try sm.appendTo(w, output.name)
- finally w.close()
- }
- }
-
- private def closureOptions(optConfig: OptimizerConfig,
- noSourceMap: Boolean = false) = {
-
- val options = new ClosureOptions
- options.prettyPrint = optConfig.prettyPrint
- CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options)
- options.setLanguageIn(ClosureOptions.LanguageMode.ECMASCRIPT5)
- options.setCheckGlobalThisLevel(CheckLevel.OFF)
-
- if (!noSourceMap && optConfig.wantSourceMap) {
- options.setSourceMapOutputPath(optConfig.output.name + ".map")
- options.setSourceMapDetailLevel(SourceMap.DetailLevel.ALL)
- }
-
- options
- }
-
- private def closureCompiler(logger: Logger) = {
- val compiler = new ClosureCompiler
- compiler.setErrorManager(new LoggerErrorManager(logger))
- compiler
- }
-}
-
-object ScalaJSClosureOptimizer {
- /** Inputs of the Scala.js Closure optimizer. */
- final case class Inputs[T](
- /** Input to optimize (classpath or file-list) */
- input: T,
- /** Additional externs files to be given to Closure. */
- additionalExterns: Seq[VirtualJSFile] = Nil,
- /** Additional exports to be given to Closure.
- * These files are just appended to the classpath, given to Closure,
- * but not used in the Scala.js optimizer pass when direct optimizing
- */
- additionalExports: Seq[VirtualJSFile] = Nil
- )
-
- /** Configuration the closure part of the optimizer needs.
- * See [[OutputConfig]] for a description of the fields.
- */
- trait OptimizerConfig {
- val output: WritableVirtualJSFile
- val cache: Option[WritableVirtualTextFile]
- val wantSourceMap: Boolean
- val prettyPrint: Boolean
- val relativizeSourceMapBase: Option[URI]
- }
-
- /** Configuration for the output of the Scala.js Closure optimizer */
- final case class OutputConfig(
- /** Writer for the output */
- output: WritableVirtualJSFile,
- /** Cache file */
- cache: Option[WritableVirtualTextFile] = None,
- /** If true, performs expensive checks of the IR for the used parts. */
- checkIR: Boolean = false,
- /** If true, the optimizer removes trees that have not been used in the
- * last run from the cache. Otherwise, all trees that has been used once,
- * are kept in memory. */
- unCache: Boolean = true,
- /** If true, no optimizations are performed */
- disableOptimizer: Boolean = false,
- /** If true, nothing is performed incrementally */
- batchMode: Boolean = false,
- /** Ask to produce source map for the output */
- wantSourceMap: Boolean = false,
- /** Pretty-print the output. */
- prettyPrint: Boolean = false,
- /** Base path to relativize paths in the source map */
- relativizeSourceMapBase: Option[URI] = None
- ) extends OptimizerConfig with ScalaJSOptimizer.OptimizerConfig
-
- /** Minimal set of externs to compile Scala.js-emitted code with Closure. */
- val ScalaJSExterns = """
- /** @constructor */
- function Object() {}
- Object.protoype.toString = function() {};
- /** @constructor */
- function Array() {}
- Array.prototype.length = 0;
- /** @constructor */
- function Function() {}
- Function.prototype.constructor = function() {};
- Function.prototype.call = function() {};
- Function.prototype.apply = function() {};
- var global = {};
- var __ScalaJSEnv = {};
- """
-
- val ScalaJSExternsFile = new MemVirtualJSFile("ScalaJSExterns.js").
- withContent(ScalaJSExterns)
-
-}