|
Scala example source code file (Names.scala)
The Scala Names.scala source code/* NSC -- new Scala compiler * Copyright 2005-2011 LAMP/EPFL * @author Martin Odersky */ package scala.tools.nsc package symtab import scala.reflect.NameTransformer import scala.io.Codec import java.security.MessageDigest /** The class Names ... * * @author Martin Odersky * @version 1.0, 05/02/2005 */ trait Names extends reflect.generic.Names { // Operations ------------------------------------------------------------- private final val HASH_SIZE = 0x8000 private final val HASH_MASK = 0x7FFF private final val NAME_SIZE = 0x20000 final val nameDebug = false /** memory to store all names sequentially */ var chrs: Array[Char] = new Array[Char](NAME_SIZE) private var nc = 0 /** hashtable for finding term names quickly */ private val termHashtable = new Array[TermName](HASH_SIZE) /** hashtable for finding type names quickly */ private val typeHashtable = new Array[TypeName](HASH_SIZE) /** the hashcode of a name */ private def hashValue(cs: Array[Char], offset: Int, len: Int): Int = if (len > 0) (len * (41 * 41 * 41) + cs(offset) * (41 * 41) + cs(offset + len - 1) * 41 + cs(offset + (len >> 1))) else 0; /** Is (the ASCII representation of) name at given index equal to * cs[offset..offset+len-1]? */ private def equals(index: Int, cs: Array[Char], offset: Int, len: Int): Boolean = { var i = 0 while ((i < len) && (chrs(index + i) == cs(offset + i))) i += 1; i == len } /** enter characters into chrs array */ private def enterChars(cs: Array[Char], offset: Int, len: Int) { var i = 0 while (i < len) { if (nc + i == chrs.length) { val newchrs = new Array[Char](chrs.length * 2) compat.Platform.arraycopy(chrs, 0, newchrs, 0, chrs.length) chrs = newchrs } chrs(nc + i) = cs(offset + i) i += 1 } if (len == 0) nc += 1 else nc = nc + len } /** Create a term name from the characters in cs[offset..offset+len-1]. */ def newTermName(cs: Array[Char], offset: Int, len: Int): TermName = { val h = hashValue(cs, offset, len) & HASH_MASK var n = termHashtable(h) while ((n ne null) && (n.length != len || !equals(n.start, cs, offset, len))) n = n.next; if (n eq null) { n = new TermName(nc, len, h) enterChars(cs, offset, len) } n } /** create a term name from string */ def newTermName(s: String): TermName = newTermName(s.toCharArray(), 0, s.length()) /** Create a term name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */ def newTermName(bs: Array[Byte], offset: Int, len: Int): TermName = { val chars = Codec fromUTF8 bs.slice(offset, offset + len) newTermName(chars, 0, chars.length) } /** Create a type name from the characters in cs[offset..offset+len-1]. */ def newTypeName(cs: Array[Char], offset: Int, len: Int): TypeName = newTermName(cs, offset, len).toTypeName /** Create a type name from string */ def newTypeName(s: String): TypeName = newTermName(s).toTypeName /** Create a type name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */ def newTypeName(bs: Array[Byte], offset: Int, len: Int): TypeName = newTermName(bs, offset, len).toTypeName def mkTermName(name: Name): TermName = name.toTermName def mkTypeName(name: Name): TypeName = name.toTypeName def isTermName(name: Name): Boolean = name.isTermName def isTypeName(name: Name): Boolean = name.isTypeName def nameChars: Array[Char] = chrs @deprecated("", "2.9.0") def view(s: String): TermName = newTermName(s) // Classes ---------------------------------------------------------------------- /** The name class. */ sealed abstract class Name(protected val index: Int, protected val len: Int) extends Function1[Int, Char] { /** Index into name table */ def start: Int = index /** next name in the same hash bucket */ def next: Name /** return the length of this name */ final def length: Int = len final def isEmpty = length == 0 final def nonEmpty = !isEmpty def isTermName: Boolean def isTypeName: Boolean def toTermName: TermName def toTypeName: TypeName def companionName: Name def bothNames: List[Name] = List(toTermName, toTypeName) /** Copy bytes of this name to buffer cs, starting at position `offset`. */ final def copyChars(cs: Array[Char], offset: Int) = compat.Platform.arraycopy(chrs, index, cs, offset, len) /** return the ascii representation of this name */ final def toChars: Array[Char] = { val cs = new Array[Char](len) copyChars(cs, 0) cs } /** return the string representation of this name */ final override def toString(): String = new String(chrs, index, len) def debugString() = NameTransformer.decode(toString) + (if (isTypeName) "!" else "") /** Write to UTF8 representation of this name to given character array. * Start copying to index `to'. Return index of next free byte in array. * Array must have enough remaining space for all bytes * (i.e. maximally 3*length bytes). */ final def copyUTF8(bs: Array[Byte], offset: Int): Int = { val bytes = Codec toUTF8 chrs.slice(index, index + len) compat.Platform.arraycopy(bytes, 0, bs, offset, bytes.length) offset + bytes.length } /** return the hash value of this name */ final override def hashCode(): Int = index // Presently disabled. // override def equals(other: Any) = paranoidEquals(other) private def paranoidEquals(other: Any): Boolean = { val cmp = this eq other.asInstanceOf[AnyRef] if (cmp || !nameDebug) return cmp other match { case x: String => Console.println("Compared " + debugString + " and String '" + x + "'") case x: Name => if (this.isTermName != x.isTermName) { val panic = this.toTermName == x.toTermName Console.println("Compared '%s' and '%s', one term, one type.%s".format(this, x, if (panic) " And they contain the same name string!" else "" )) } case _ => } false } /** return the i'th Char of this name */ final def apply(i: Int): Char = chrs(index + i) /** return the index of first occurrence of char c in this name, length if not found */ final def pos(c: Char): Int = pos(c, 0) /** return the index of first occurrence of char c in this name, length if not found */ final def pos(s: String): Int = pos(s, 0) /** return the index of the first occurrence of character c in * this name from start, length if not found. * * @param c the character * @param start ... * @return the index of the first occurrence of c */ final def pos(c: Char, start: Int): Int = { var i = start while (i < len && chrs(index + i) != c) i += 1 i } /** return the index of the first occurrence of nonempty string s * in this name from start, length if not found. * * @param s the string * @param start ... * @return the index of the first occurrence of s */ final def pos(s: String, start: Int): Int = { var i = pos(s.charAt(0), start) while (i + s.length() <= len) { var j = 1 while (s.charAt(j) == chrs(index + i + j)) { j += 1 if (j == s.length()) return i } i = pos(s.charAt(0), i + 1) } len } /** return the index of last occurrence of char c in this * name, -1 if not found. * * @param c the character * @return the index of the last occurrence of c */ final def lastPos(c: Char): Int = lastPos(c, len - 1) final def lastPos(s: String): Int = lastPos(s, len - s.length) /** return the index of the last occurrence of char c in this * name from start, -1 if not found. * * @param c the character * @param start ... * @return the index of the last occurrence of c */ final def lastPos(c: Char, start: Int): Int = { var i = start while (i >= 0 && chrs(index + i) != c) i -= 1 i } /** return the index of the last occurrence of string s in this * name from start, -1 if not found. * * @param s the string * @param start ... * @return the index of the last occurrence of s */ final def lastPos(s: String, start: Int): Int = { var i = lastPos(s.charAt(0), start) while (i >= 0) { var j = 1; while (s.charAt(j) == chrs(index + i + j)) { j += 1 if (j == s.length()) return i; } i = lastPos(s.charAt(0), i - 1) } -s.length() } /** does this name start with prefix? */ final def startsWith(prefix: Name): Boolean = startsWith(prefix, 0) /** does this name start with prefix at given start index? */ final def startsWith(prefix: Name, start: Int): Boolean = { var i = 0 while (i < prefix.length && start + i < len && chrs(index + start + i) == chrs(prefix.start + i)) i += 1; i == prefix.length } /** does this name end with suffix? */ final def endsWith(suffix: Name): Boolean = endsWith(suffix, len) /** does this name end with suffix just before given end index? */ final def endsWith(suffix: Name, end: Int): Boolean = { var i = 1 while (i <= suffix.length && i <= end && chrs(index + end - i) == chrs(suffix.start + suffix.length - i)) i += 1; i > suffix.length } final def containsName(subname: String): Boolean = containsName(newTermName(subname)) final def containsName(subname: Name): Boolean = { var start = 0 val last = len - subname.length while (start <= last && !startsWith(subname, start)) start += 1 start <= last } /** Some thoroughly self-explanatory convenience functions. They * assume that what they're being asked to do is known to be valid. */ final def startChar: Char = apply(0) final def endChar: Char = apply(len - 1) final def startsWith(char: Char): Boolean = len > 0 && startChar == char final def startsWith(name: String): Boolean = startsWith(newTermName(name)) final def endsWith(char: Char): Boolean = len > 0 && endChar == char final def endsWith(name: String): Boolean = endsWith(newTermName(name)) final def stripStart(prefix: Name): Name = subName(prefix.length, len) final def stripStart(prefix: String): Name = subName(prefix.length, len) final def stripEnd(suffix: Name): Name = subName(0, len - suffix.length) final def stripEnd(suffix: String): Name = subName(0, len - suffix.length) def lastIndexOf(ch: Char) = toChars lastIndexOf ch /** Return the subname with characters from start to end-1. */ def subName(from: Int, to: Int): Name /** Replace all occurrences of `from` by `to` in * name; result is always a term name. */ def replace(from: Char, to: Char): Name = { val cs = new Array[Char](len) var i = 0 while (i < len) { val ch = this(i) cs(i) = if (ch == from) to else ch i += 1 } newTermName(cs, 0, len) } /** Replace operator symbols by corresponding $op_name. */ def encode: Name = { val str = toString() val res = NameTransformer.encode(str) if (res == str) this else if (isTypeName) newTypeName(res) else newTermName(res) } def append(suffix: String): Name def append(suffix: Name): Name /** Replace $op_name by corresponding operator symbol. */ def decode: String = ( NameTransformer.decode(toString()) + (if (nameDebug && isTypeName) "!" else ""))//debug def isOperatorName: Boolean = decode != toString def nameKind: String = if (isTypeName) "type" else "term" def longString: String = nameKind + " " + NameTransformer.decode(toString) } final class TermName(_index: Int, _len: Int, hash: Int) extends Name(_index, _len) { var next: TermName = termHashtable(hash) termHashtable(hash) = this def isTermName: Boolean = true def isTypeName: Boolean = false def toTermName: TermName = this def toTypeName: TypeName = { val h = hashValue(chrs, index, len) & HASH_MASK var n = typeHashtable(h) while ((n ne null) && n.start != index) n = n.next; if (n eq null) n = new TypeName(index, len, h); n } def append(suffix: String): TermName = newTermName(this + suffix) def append(suffix: Name): TermName = append(suffix.toString) def companionName: TypeName = toTypeName def subName(from: Int, to: Int): TermName = newTermName(chrs, start + from, to - from) } final class TypeName(_index: Int, _len: Int, hash: Int) extends Name(_index, _len) { var next: TypeName = typeHashtable(hash) typeHashtable(hash) = this def isTermName: Boolean = false def isTypeName: Boolean = true def toTermName: TermName = { val h = hashValue(chrs, index, len) & HASH_MASK var n = termHashtable(h) while ((n ne null) && n.start != index) n = n.next; if (n eq null) n = new TermName(index, len, h); n } def toTypeName: TypeName = this def append(suffix: String): TypeName = newTypeName(this + suffix) def append(suffix: Name): TypeName = append(suffix.toString) def companionName: TermName = toTermName def subName(from: Int, to: Int): TypeName = newTypeName(chrs, start + from, to - from) } } Other Scala examples (source code examples)Here is a short list of links related to this Scala Names.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.