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
}
}
}
|