From 712ebe2943640b34ff40b40a363bd72594e62cb5 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 21 May 2010 17:07:50 +0000 Subject: Altered a bunch of places which call hashCode t... Altered a bunch of places which call hashCode to call ## instead. No review. --- src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 4 ++-- src/compiler/scala/tools/nsc/io/VirtualFile.scala | 2 +- src/compiler/scala/tools/nsc/symtab/Types.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 3 +-- src/compiler/scala/tools/nsc/typechecker/Namers.scala | 2 +- src/compiler/scala/tools/nsc/util/HashSet.scala | 8 ++++---- src/library/scala/Enumeration.scala | 2 +- src/library/scala/Proxy.scala | 2 +- src/library/scala/collection/MapLike.scala | 2 +- src/library/scala/collection/SeqLike.scala | 2 +- src/library/scala/collection/immutable/HashMap.scala | 2 +- src/library/scala/collection/immutable/HashSet.scala | 2 +- src/library/scala/collection/immutable/TreeHashMap.scala | 2 +- src/library/scala/collection/mutable/HashTable.scala | 2 +- src/library/scala/collection/mutable/LinkedHashSet.scala | 2 +- src/library/scala/collection/mutable/OpenHashMap.scala | 2 +- src/library/scala/math/BigDecimal.scala | 2 +- src/library/scala/math/BigInt.scala | 2 +- src/library/scala/math/ScalaNumericConversions.scala | 2 +- src/library/scala/reflect/ClassManifest.scala | 2 +- src/library/scala/reflect/Manifest.scala | 2 +- src/library/scala/reflect/generic/Constants.scala | 2 +- src/library/scala/runtime/ScalaRunTime.scala | 5 ++++- src/library/scala/util/JenkinsHash.scala | 2 +- src/library/scala/xml/Equality.scala | 2 +- src/library/scala/xml/Utility.scala | 6 +++--- src/library/scala/xml/factory/LoggedNodeFactory.scala | 2 +- src/library/scala/xml/factory/NodeFactory.scala | 2 +- src/msil/ch/epfl/lamp/compiler/msil/Type.java | 2 +- src/swing/scala/swing/Publisher.scala | 2 +- 31 files changed, 40 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 779e16aad4..ffdedd0cfc 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1700,7 +1700,7 @@ abstract class GenJVM extends SubComponent { def indexOf(local: Local): Int = { assert(local.index >= 0, - "Invalid index for: " + local + "{" + local.hashCode + "}: ") + "Invalid index for: " + local + "{" + local.## + "}: ") local.index } @@ -1715,7 +1715,7 @@ abstract class GenJVM extends SubComponent { for (l <- m.locals) { if (settings.debug.value) - log("Index value for " + l + "{" + l.hashCode + "}: " + idx) + log("Index value for " + l + "{" + l.## + "}: " + idx) l.index = idx idx += sizeOf(l.kind) } diff --git a/src/compiler/scala/tools/nsc/io/VirtualFile.scala b/src/compiler/scala/tools/nsc/io/VirtualFile.scala index 005ede4843..421e39195d 100644 --- a/src/compiler/scala/tools/nsc/io/VirtualFile.scala +++ b/src/compiler/scala/tools/nsc/io/VirtualFile.scala @@ -31,7 +31,7 @@ class VirtualFile(val name: String, _path: String) extends AbstractFile */ def this(name: String) = this(name, name) - override def hashCode = name.hashCode + override def hashCode = name.## override def equals(that: Any) = cond(that) { case x: VirtualFile => x.name == name } //######################################################################## diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index dc59587c4a..e0987c2d8b 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -2301,7 +2301,7 @@ A type's typeSymbol should never be inspected directly. origin+ (if(typeArgs.isEmpty) "" else (typeArgs map (_.safeToString)).mkString("[ ", ", ", " ]")) // +"#"+tid //DEBUG if (constr.inst eq null) "" - else if (settings.debug.value) varString+"(@"+constr.hashCode+")"+constr.toString + else if (settings.debug.value) varString+"(@"+constr.## +")"+constr.toString else if (constr.inst eq NoType) varString else constr.inst.toString } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index afe5e2fddd..7469388a08 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -316,7 +316,7 @@ trait Contexts { self: Analyzer => override def toString(): String = { if (this == NoContext) "NoContext" else owner.toString() + " @ " + tree.getClass() + - " " + tree.toString() + ", scope = " + scope.hashCode() + + " " + tree.toString() + ", scope = " + scope.## + " " + scope.toList + "\n:: " + outer.toString() } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 66547fbd2f..20d367337f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -126,8 +126,7 @@ self: Analyzer => case _ => false } - override def hashCode = - name.hashCode + pre.hashCode + sym.hashCode + override def hashCode = name.## + pre.## + sym.## override def toString = "ImplicitInfo(" + name + "," + pre + "," + sym + ")" } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 03b2d5574c..d56b8ed944 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -297,7 +297,7 @@ trait Namers { self: Analyzer => private def enterSymFinishWith(tree: Tree, tparams: List[TypeDef]) { val sym = tree.symbol - if (settings.debug.value) log("entered " + sym + " in " + context.owner + ", scope-id = " + context.scope.hashCode()); + if (settings.debug.value) log("entered " + sym + " in " + context.owner + ", scope-id = " + context.scope.## ) var ltype = namerOf(sym).typeCompleter(tree) if (!tparams.isEmpty) { //@M! TypeDef's type params are handled differently diff --git a/src/compiler/scala/tools/nsc/util/HashSet.scala b/src/compiler/scala/tools/nsc/util/HashSet.scala index 72448fb19a..aa6e19538c 100644 --- a/src/compiler/scala/tools/nsc/util/HashSet.scala +++ b/src/compiler/scala/tools/nsc/util/HashSet.scala @@ -26,7 +26,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte private def index(x: Int): Int = math.abs(x % capacity) def findEntryOrUpdate(x: T): T = { - var h = index(x.hashCode()) + var h = index(x.##) var entry = table(h) while (entry ne null) { if (x == entry) @@ -42,7 +42,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte } def findEntry(x: T): T = { - var h = index(x.hashCode()) + var h = index(x.##) var entry = table(h) while ((entry ne null) && entry != x) { h = index(h + 1) @@ -52,7 +52,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte } def addEntry(x: T) { - var h = index(x.hashCode()) + var h = index(x.##) var entry = table(h) while (entry ne null) { if (entry == x) return @@ -76,7 +76,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte } private def addOldEntry(x: T) { - var h = index(x.hashCode()) + var h = index(x.##) var entry = table(h) while (entry ne null) { h = index(h + 1) diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index ab944b20a8..5d1a0997ed 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -230,7 +230,7 @@ abstract class Enumeration(initial: Int, names: String*) { thisenum => case that: thisenum.Value => compare(that) == 0 case _ => false } - override def hashCode: Int = id.hashCode + override def hashCode: Int = id.## /** this enumeration value as an Int bit mask. * @throws IllegalArgumentException if id is greater than 31 diff --git a/src/library/scala/Proxy.scala b/src/library/scala/Proxy.scala index d37b8f5e5d..feac5904a5 100644 --- a/src/library/scala/Proxy.scala +++ b/src/library/scala/Proxy.scala @@ -21,7 +21,7 @@ package scala */ trait Proxy { def self: Any - override def hashCode: Int = self.hashCode + override def hashCode: Int = self.## override def equals(that: Any): Boolean = if(that == null) false else that equals self diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala index 9edc2904e1..fdaee64fd5 100644 --- a/src/library/scala/collection/MapLike.scala +++ b/src/library/scala/collection/MapLike.scala @@ -329,7 +329,7 @@ self => override /*PartialFunction*/ def toString = super[IterableLike].toString - override def hashCode() = this map (_.hashCode) sum + override def hashCode() = this map (_.##) sum /** Compares two maps structurally; i.e. checks if all mappings * contained in this map are also contained in the other map, diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index 5f75169f3c..8770de9c36 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -857,7 +857,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => /** Hashcodes for $Coll produce a value from the hashcodes of all the * elements of the $coll. */ - override def hashCode() = (Seq.hashSeed /: this)(_ * 41 + _.hashCode) + override def hashCode() = (Seq.hashSeed /: this)(_ * 41 + _.##) override def equals(that: Any): Boolean = that match { case that: Seq[_] => (that canEqual this) && (this sameElements that) diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 71de59b861..01ef597d24 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -58,7 +58,7 @@ class HashMap[A, +B] extends Map[A,B] with MapLike[A, B, HashMap[A, B]] { def - (key: A): HashMap[A, B] = removed0(key, computeHash(key), 0) - protected def elemHashCode(key: A) = if (key == null) 0 else key.hashCode() + protected def elemHashCode(key: A) = if (key == null) 0 else key.## protected final def improve(hcode: Int) = { var h: Int = hcode + ~(hcode << 9) diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index 8f77c2e916..08e64d6709 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -55,7 +55,7 @@ class HashSet[A] extends Set[A] def - (e: A): HashSet[A] = removed0(e, computeHash(e), 0) - protected def elemHashCode(key: A) = if (key == null) 0 else key.hashCode() + protected def elemHashCode(key: A) = if (key == null) 0 else key.## protected final def improve(hcode: Int) = { var h: Int = hcode + ~(hcode << 9) diff --git a/src/library/scala/collection/immutable/TreeHashMap.scala b/src/library/scala/collection/immutable/TreeHashMap.scala index 1a2d34cc38..a7de5bf8d1 100644 --- a/src/library/scala/collection/immutable/TreeHashMap.scala +++ b/src/library/scala/collection/immutable/TreeHashMap.scala @@ -54,7 +54,7 @@ class TreeHashMap[Key, +Value] private (private val underlying : IntMap[AssocMap def empty[V] = TreeHashMap.empty[Key, V] private def hash(key : Key) = { - var h = key.hashCode; + var h = key.## h ^= ((h >>> 20) ^ (h >>> 12)); h ^ (h >>> 7) ^ (h >>> 4); } diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index be266be543..b924a38dde 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -228,7 +228,7 @@ trait HashTable[A] { protected def elemEquals(key1: A, key2: A): Boolean = (key1 == key2) - protected def elemHashCode(key: A) = if (key == null) 0 else key.hashCode() + protected def elemHashCode(key: A) = if (key == null) 0 else key.## protected final def improve(hcode: Int) = { var h: Int = hcode + ~(hcode << 9) diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index 71f38182db..922ff25276 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -68,7 +68,7 @@ class LinkedHashSet[A] extends Set[A] clearTable() } - override def iterator = ordered.iterator + override def iterator: Iterator[A] = ordered.iterator override def foreach[U](f: A => U) = ordered foreach f diff --git a/src/library/scala/collection/mutable/OpenHashMap.scala b/src/library/scala/collection/mutable/OpenHashMap.scala index 9c1560ad24..b10b88049e 100644 --- a/src/library/scala/collection/mutable/OpenHashMap.scala +++ b/src/library/scala/collection/mutable/OpenHashMap.scala @@ -91,7 +91,7 @@ extends Map[Key, Value] /** Returns a mangled hash code of the provided key. */ protected def hashOf(key : Key) = { - var h = key.hashCode; + var h = key.## h ^= ((h >>> 20) ^ (h >>> 12)); h ^ (h >>> 7) ^ (h >>> 4); } diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index 7312c0d2c0..e1d44862e4 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -173,7 +173,7 @@ extends ScalaNumber with ScalaNumericConversions */ override def hashCode(): Int = if (isWhole) unifiedPrimitiveHashcode - else doubleValue.hashCode() + else doubleValue.## /** Compares this BigDecimal with the specified value for equality. */ diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index aef48806c2..79b377bc6c 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -116,7 +116,7 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo /** Returns the hash code for this BigInt. */ override def hashCode(): Int = if (this >= BigInt.MinLong && this <= BigInt.MaxLong) unifiedPrimitiveHashcode - else bigInteger.hashCode + else bigInteger.## /** Compares this BigInt with the specified value for equality. */ diff --git a/src/library/scala/math/ScalaNumericConversions.scala b/src/library/scala/math/ScalaNumericConversions.scala index 2e754c2584..34698ea39f 100644 --- a/src/library/scala/math/ScalaNumericConversions.scala +++ b/src/library/scala/math/ScalaNumericConversions.scala @@ -30,7 +30,7 @@ trait ScalaNumericConversions extends ScalaNumber { protected def unifiedPrimitiveHashcode() = { val lv = toLong if (lv >= Int.MinValue && lv <= Int.MaxValue) lv.toInt - else lv.hashCode + else lv.## } /** Should only be called after all known non-primitive diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala index 777908d142..0337ed6aed 100644 --- a/src/library/scala/reflect/ClassManifest.scala +++ b/src/library/scala/reflect/ClassManifest.scala @@ -85,7 +85,7 @@ trait ClassManifest[T] extends OptManifest[T] with Equals { case m: ClassManifest[_] if m canEqual this => this.erasure == m.erasure case _ => false } - override def hashCode = this.erasure.hashCode + override def hashCode = this.erasure.## protected def arrayClass[T](tp: Predef.Class[_]): Predef.Class[Array[T]] = java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[Predef.Class[Array[T]]] diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala index 1009ca8c85..6faa99c4c8 100644 --- a/src/library/scala/reflect/Manifest.scala +++ b/src/library/scala/reflect/Manifest.scala @@ -40,7 +40,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals { case m: Manifest[_] if m canEqual this => (this <:< m) && (m <:< this) case _ => false } - override def hashCode = this.erasure.hashCode + override def hashCode = this.erasure.## } @serializable diff --git a/src/library/scala/reflect/generic/Constants.scala b/src/library/scala/reflect/generic/Constants.scala index d9faac653f..bf963a1aae 100755 --- a/src/library/scala/reflect/generic/Constants.scala +++ b/src/library/scala/reflect/generic/Constants.scala @@ -230,6 +230,6 @@ trait Constants { self: Universe => def symbolValue: Symbol = value.asInstanceOf[Symbol] override def hashCode: Int = - if (value == null) 0 else value.hashCode() * 41 + 17 + if (value == null) 0 else value.## * 41 + 17 } } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index bc28e48163..26dc0830e5 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -154,7 +154,7 @@ object ScalaRunTime { var i = 0 while (i < arr) { val elem = x.productElement(i) - code = code * 41 + (if (elem == null) 0 else elem.hashCode()) + code = code * 41 + (if (elem == null) 0 else elem.##) i += 1 } code @@ -175,6 +175,9 @@ object ScalaRunTime { } // hashcode ----------------------------------------------------------- + // + // Note that these are the implementations called by ##, so they + // must not call ## themselves. @inline def hash(x: Any): Int = if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) diff --git a/src/library/scala/util/JenkinsHash.scala b/src/library/scala/util/JenkinsHash.scala index fcd263f5c9..83df5ad834 100644 --- a/src/library/scala/util/JenkinsHash.scala +++ b/src/library/scala/util/JenkinsHash.scala @@ -124,7 +124,7 @@ object JenkinsHash { */ def hashSeq(xs: Seq[Any]): Int = { val (values, refs) = partitionValuesAndRefs(xs) - val refsSum = refs map (x => if (x == null) 0 else x.hashCode) sum + val refsSum = refs map (x => if (x == null) 0 else x.##) sum hashAnyValSeq(values) + refsSum } diff --git a/src/library/scala/xml/Equality.scala b/src/library/scala/xml/Equality.scala index d09ae10b2d..210029b3bd 100644 --- a/src/library/scala/xml/Equality.scala +++ b/src/library/scala/xml/Equality.scala @@ -74,7 +74,7 @@ trait Equality extends scala.Equals { def strict_==(other: Equality): Boolean def strict_!=(other: Equality) = !strict_==(other) - private def hashOf(x: Any) = if (x == null) 1 else x.hashCode() + private def hashOf(x: Any) = if (x == null) 1 else x.## /** We insist we're only equal to other xml.Equality implementors, * which heads off a lot of inconsistency up front. diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 9880e7bd4b..65d7179fa2 100644 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -261,14 +261,14 @@ object Utility extends AnyRef with parsing.TokenTests * @param children */ def hashCode(pre: String, label: String, attribHashCode: Int, scpeHash: Int, children: Seq[Node]) = ( - ( if(pre ne null) {41 * pre.hashCode() % 7} else {0}) - + label.hashCode() * 53 + ( if(pre ne null) {41 * pre.## % 7} else {0}) + + label.## * 53 + attribHashCode * 7 + scpeHash * 31 + { var c = 0 val i = children.iterator - while(i.hasNext) c = c * 41 + i.next.hashCode + while(i.hasNext) c = c * 41 + i.next.## c } ) diff --git a/src/library/scala/xml/factory/LoggedNodeFactory.scala b/src/library/scala/xml/factory/LoggedNodeFactory.scala index 8c965128ee..2159f8c106 100644 --- a/src/library/scala/xml/factory/LoggedNodeFactory.scala +++ b/src/library/scala/xml/factory/LoggedNodeFactory.scala @@ -58,7 +58,7 @@ with scala.util.logging.Logged { if (logNode) log("[makeNode for "+label+"]"); - val hash = Utility.hashCode(pre, label, attrSeq.hashCode(), scope.hashCode(), children) + val hash = Utility.hashCode(pre, label, attrSeq.##, scope.##, children) /* if(logCompressLevel >= FULL) { diff --git a/src/library/scala/xml/factory/NodeFactory.scala b/src/library/scala/xml/factory/NodeFactory.scala index 7613041f04..4178a38cd9 100644 --- a/src/library/scala/xml/factory/NodeFactory.scala +++ b/src/library/scala/xml/factory/NodeFactory.scala @@ -40,7 +40,7 @@ trait NodeFactory[A <: Node] eqElements(n.child, children) def makeNode(pre: String, name: String, attrSeq: MetaData, scope: NamespaceBinding, children: Seq[Node]): A = { - val hash = Utility.hashCode( pre, name, attrSeq.hashCode(), scope.hashCode(), children) + val hash = Utility.hashCode( pre, name, attrSeq.##, scope.##, children) def cons(old: List[A]) = construct(hash, old, pre, name, attrSeq, scope, children) (cache get hash) match { diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Type.java b/src/msil/ch/epfl/lamp/compiler/msil/Type.java index f7d44980c4..dbeaa1184a 100644 --- a/src/msil/ch/epfl/lamp/compiler/msil/Type.java +++ b/src/msil/ch/epfl/lamp/compiler/msil/Type.java @@ -812,7 +812,7 @@ public abstract class Type extends MemberInfo { if (k >= 0) cname = cname.substring(k + 1); return "[" + t.Assembly().GetName() + "]" + t + - "(" + cname + "#" + Integer.toHexString(t.hashCode()) + ")"; + "(" + cname + "#" + Integer.toHexString(t.##) + ")"; } private static String dumpType(Type t) { StringBuffer str = new StringBuffer(); diff --git a/src/swing/scala/swing/Publisher.scala b/src/swing/scala/swing/Publisher.scala index cb85864c62..3fa9fc7e56 100644 --- a/src/swing/scala/swing/Publisher.scala +++ b/src/swing/scala/swing/Publisher.scala @@ -80,7 +80,7 @@ private[swing] trait SingleRefCollection[+A <: AnyRef] extends Iterable[A] { sel trait Ref[+A <: AnyRef] extends Reference[A] { override def hashCode() = { val v = get - if (v == None) 0 else v.get.hashCode + if (v == None) 0 else v.get.## } override def equals(that: Any) = that match { case that: ReferenceWrapper[_] => -- cgit v1.2.3