summaryrefslogtreecommitdiff
path: root/src/main/scala/forge/Util.scala
blob: e558e9754d6f1e7a5e2947fedb9830d210468b53 (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package forge

import java.io.FileOutputStream
import java.nio.{file => jnio}
import java.util.jar.JarEntry

import sourcecode.Enclosing

import scala.collection.JavaConverters._
import scala.collection.mutable

class MultiBiMap[K, V](){
  private[this] val valueToKey = mutable.Map.empty[V, K]
  private[this] val keyToValues = mutable.Map.empty[K, List[V]]
  def containsValue(v: V) = valueToKey.contains(v)
  def lookupValue(v: V) = valueToKey(v)
  def lookupValueOpt(v: V) = valueToKey.get(v)
  def add(k: K, v: V): Unit = {
    valueToKey(v) = k
    keyToValues(k) = v :: keyToValues.getOrElse(k, Nil)
  }
  def removeAll(k: K): Seq[V] = keyToValues.get(k) match {
    case None => Nil
    case Some(vs) =>
      vs.foreach(valueToKey.remove)

      keyToValues.remove(k)
      vs
  }
  def addAll(k: K, vs: Seq[V]): Unit = {
    vs.foreach(valueToKey.update(_, k))
    keyToValues(k) = vs ++: keyToValues.getOrElse(k, Nil)
  }
}

/**
  * A collection with enforced uniqueness, fast contains and deterministic
  * ordering. When a duplicate happens, it can be configured to either remove
  * it automatically or to throw an exception and fail loudly
  */
trait OSet[V] extends TraversableOnce[V]{
  def contains(v: V): Boolean
  def items: IndexedSeq[V]
  def flatMap[T](f: V => TraversableOnce[T]): OSet[T]
  def map[T](f: V => T): OSet[T]
  def filter(f: V => Boolean): OSet[V]


}
object OSet{
  def apply[V](items: V*) = from(items)
  def dedup[V](items: V*) = from(items, dedup = true)

  def from[V](items: TraversableOnce[V], dedup: Boolean = false): OSet[V] = {
    val set = new MutableOSet[V](dedup)
    items.foreach(set.append)
    set
  }
}
class MutableOSet[V](dedup: Boolean = false) extends OSet[V]{
  private[this] val items0 = mutable.ArrayBuffer.empty[V]
  private[this] val set0 = mutable.Set.empty[V]
  def contains(v: V) = set0.contains(v)
  def append(v: V) = if (!contains(v)){
    set0.add(v)
    items0.append(v)
  }else if (!dedup) {
    throw new Exception("Duplicated item inserted into OrderedSet: " + v)
  }
  def appendAll(vs: Seq[V]) = vs.foreach(append)
  def items: IndexedSeq[V] = items0
  def set: collection.Set[V] = set0

  def map[T](f: V => T): OSet[T] = {
    val output = new MutableOSet[T]
    for(i <- items) output.append(f(i))
    output
  }
  def flatMap[T](f: V => TraversableOnce[T]): OSet[T] = {
    val output = new MutableOSet[T]
    for(i <- items) for(i0 <- f(i)) output.append(i0)
    output
  }
  def filter(f: V => Boolean): OSet[V] = {
    val output = new MutableOSet[V]
    for(i <- items) if (f(i)) output.append(i)
    output
  }

  // Members declared in scala.collection.GenTraversableOnce
  def isTraversableAgain: Boolean = items.isTraversableAgain
  def toIterator: Iterator[V] = items.toIterator
  def toStream: Stream[V] = items.toStream

  // Members declared in scala.collection.TraversableOnce
  def copyToArray[B >: V](xs: Array[B],start: Int,len: Int): Unit = items.copyToArray(xs, start, len)
  def exists(p: V => Boolean): Boolean = items.exists(p)
  def find(p: V => Boolean): Option[V] = items.find(p)
  def forall(p: V => Boolean): Boolean = items.forall(p)
  def foreach[U](f: V => U): Unit = items.foreach(f)
  def hasDefiniteSize: Boolean = items.hasDefiniteSize
  def isEmpty: Boolean = items.isEmpty
  def seq: scala.collection.TraversableOnce[V] = items
  def toTraversable: Traversable[V] = items

  override def hashCode() = items.hashCode()
  override def equals(other: Any) = other match{
    case s: OSet[_] => items.equals(s.items)
    case _ => super.equals(other)
  }
  override def toString = items.mkString("OSet(", ", ", ")")
}
object Util{
  def compileAll(sources: Target[Seq[jnio.Path]])
                (implicit defCtx: DefCtx) = {
    new Target.Subprocess(
      Seq(sources),
      args =>
        Seq("javac") ++
        args[Seq[jnio.Path]](0).map(_.toAbsolutePath.toString) ++
        Seq("-d", args.dest.toAbsolutePath.toString),
      defCtx
    ).map(_.dest)
  }

  def list(root: Target[jnio.Path])(implicit defCtx: DefCtx): Target[Seq[jnio.Path]] = {
    root.map(jnio.Files.list(_).iterator().asScala.toArray[jnio.Path])
  }
  case class jarUp(roots: Target[jnio.Path]*)(implicit val defCtx: DefCtx) extends Target[jnio.Path]{

    val inputs = roots
    def evaluate(args: Args): jnio.Path = {

      val output = new java.util.jar.JarOutputStream(new FileOutputStream(args.dest.toFile))
      for{
        root0 <- args.args
        root = root0.asInstanceOf[jnio.Path]

        path <- jnio.Files.walk(root).iterator().asScala
        if jnio.Files.isRegularFile(path)
      }{
        val relative = root.relativize(path)
        output.putNextEntry(new JarEntry(relative.toString))
        output.write(jnio.Files.readAllBytes(path))
      }
      output.close()
      args.dest
    }


  }


}