diff options
-rw-r--r-- | config/list/compiler.lst | 2 | ||||
-rw-r--r-- | sources/scalac/util/Name.java | 156 | ||||
-rw-r--r-- | sources/scalac/util/TermName.java | 104 | ||||
-rw-r--r-- | sources/scalac/util/TypeName.java | 36 |
4 files changed, 218 insertions, 80 deletions
diff --git a/config/list/compiler.lst b/config/list/compiler.lst index a768b15fe4..8c3b6ca000 100644 --- a/config/list/compiler.lst +++ b/config/list/compiler.lst @@ -164,6 +164,8 @@ util/PrefixMatcher.java util/Reporter.java util/SourceRepresentation.java util/Strings.java +util/TermName.java +util/TypeName.java util/TypeNames.java util/UniqueID.java diff --git a/sources/scalac/util/Name.java b/sources/scalac/util/Name.java index 82b1fc5055..c6da6ad003 100644 --- a/sources/scalac/util/Name.java +++ b/sources/scalac/util/Name.java @@ -2,128 +2,124 @@ ** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** ** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** ** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ \* */ +// $Id$ + package scalac.util; -import java.util.HashMap; +/** This class implements the common part of TermName and TypeName. */ +public abstract class Name { -public final class Name { + //######################################################################## + // Public Fields -/** address in the name memory - */ + /** The unique identifier */ public final int index; - private final String string; + //######################################################################## + // Private Fields + + /** The related term name */ + private final TermName term; -/** hashtable for finding term names quickly - */ - private static HashMap/*<String,TermName>*/ terms = new HashMap(); + /** The related type name (null if not yet created) */ + private TypeName type; - private final Name term; - private Name type; + //######################################################################## + // Protected Constructors -/** Constructor - */ - private Name(String string, Name dual) { - this.string = string; - this.index = dual != null ? dual.index + 1 : 2 * terms.size(); - this.term = dual != null ? dual : this; - this.type = dual != null ? this : null; - if (dual == null) terms.put(string, this); + /** Initializes this instance. */ + protected Name(int index, TermName term) { + this.index = index; + this.term = term == null ? (TermName)this : term; + this.type = term == null ? null : (TypeName)this; } -/** create a term name from the bytes in cs[offset..offset+len-1]. - * assume that bytes are in ascii format. - */ - public static Name fromAscii(byte cs[], int offset, int len) { - return fromString(SourceRepresentation.ascii2string(cs, offset, len)); + //######################################################################## + // Public Factories + + /** Returns the term name with given ASCII representation. */ + public static TermName fromAscii(byte[] bytes, int start, int count) { + return TermName.fromAscii(bytes, start, count); } -/** create a name from the characters in string s - */ - public static Name fromString(String s) { - Object value = terms.get(s); - if (value != null) return (Name)value; - return new Name(s, null); + /** Returns the term name with given string representation. */ + public static TermName fromString(String string) { + return TermName.fromString(string); } -/** return the string representation of this name - */ - public String toString() { - return string; + //######################################################################## + // Public Methods + + /** Is this name a variable identifier? */ + public final boolean isVariable() { + char first = charAt(0); + return (('a' <= first && first <= 'z') || first == '_') + && this != Names.false_ + && this != Names.true_ + && this != Names.null_; } -/** is this name a term name? - */ - public boolean isTermName() { + /** Is this name a term name? */ + public final boolean isTermName() { return this == term; } -/** is this name a type name? - */ - public boolean isTypeName() { + /** Is this name a type name? */ + public final boolean isTypeName() { return this == type; } -/** create a term name corresponding to this name - */ - public Name toTermName() { + /** Returns the term name with the same representation. */ + public final TermName toTermName() { return term; } -/** create a type name corresponding to this name - */ - public Name toTypeName() { - return type != null ? type : (type = new Name(string, this)); + /** Returns the type name with the same representation. */ + public final TypeName toTypeName() { + return type != null ? type : (type = new TypeName(term)); } -/** return the string hash value of this name - */ - public int hashCode() { - return index; + /** Returns the result of "toString().length()". */ + public final int length() { + return toString().length(); } -/** returns the length of this name - */ - public int length() { - return string.length(); + /** Returns the result of "toString().charAt(index)". */ + public final char charAt(int index) { + return toString().charAt(index); } -/** returns i'th char of this name - */ - public char charAt(int i) { - return string.charAt(i); + /** Returns the result of "toString().indexOf(ch)". */ + public final int indexOf(char ch) { + return toString().indexOf(ch); } -/** returns first occurrence of char c in this name, -1 if not found - */ - public int indexOf(char c) { - return indexOf(c, 0); + /** Returns the result of "toString().indexOf(ch, start)". */ + public final int indexOf(char ch, int start) { + return toString().indexOf(ch, start); } -/** returns first occurrence of char c in this name from `start', -1 if not found - */ - public int indexOf(char c, int start) { - return string.indexOf(c, start); + /** Returns the result of "toString().lastIndexOf(ch)". */ + public final int lastIndexOf(char ch) { + return toString().lastIndexOf(ch); } -/** returns last occurrence of char c in this name, -1 if not found. - */ - public int lastIndexOf(char c) { - return string.lastIndexOf(c); + /** Returns the result of "toString().lastIndexOf(ch, start)". */ + public final int lastIndexOf(char ch, int start) { + return toString().lastIndexOf(ch, start); } -/** is this name a variable identifier? - */ - public boolean isVariable() { - char first = string.charAt(0); - return ((first >= 'a' && first <= 'z') || first == '_') && - this != Names.null_ && - this != Names.true_ && - this != Names.false_; + /** Returns the hash code of this name. */ + public final int hashCode() { + return index; + } + + /** Returns the string representation of this name. */ + public String toString() { + return term.toString(); } + //######################################################################## } diff --git a/sources/scalac/util/TermName.java b/sources/scalac/util/TermName.java new file mode 100644 index 0000000000..be6b2511a8 --- /dev/null +++ b/sources/scalac/util/TermName.java @@ -0,0 +1,104 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scalac.util; + +import java.util.HashMap; + +/** Instances of this class represent term names. */ +public final class TermName extends Name { + + //######################################################################## + // Private Variables + + /** Hashtable from string representation to term names. */ + private static HashMap/*<String,TermName>*/ strings = new HashMap(); + + /** Hashtable from ASCII representation to term names. */ + private static TermName[] asciis = new TermName[0x00008000]; + + //######################################################################## + // Private Fields + + /** The string representation */ + private final String string; + + /** The ASCII representation (null if not yet computed) */ + private byte[] ascii; + + /** The next name stored in the same bucket of the ASCII table */ + private TermName next; + + //######################################################################## + // Private Constructors + + /** Initializes this instance. */ + private TermName(String string) { + super(2 * strings.size(), null); + this.string = string; + strings.put(string, this); + } + + //######################################################################## + // Public Factories + + /** Returns the term name with given ASCII representation. */ + public static TermName fromAscii(byte[] bytes, int start, int count) { + int index = hashValue(bytes, start, count) & (asciis.length - 1); + for (TermName name = asciis[index]; name != null; name = name.next) + if (name.equals(bytes, start, count)) return name; + TermName name = fromString(toString(bytes, start, count)); + assert name.ascii == null: name; + byte[] ascii = name.ascii = new byte[count]; + for (int i = 0; i < ascii.length; i++) ascii[i] = bytes[start + i]; + name.next = asciis[index]; + asciis[index] = name; + return name; + } + + /** Returns the term name with given string representation. */ + public static TermName fromString(String string) { + Object value = strings.get(string); + return value != null ? (TermName)value : new TermName(string); + } + + //######################################################################## + // Public Methods + + /** Returns the string representation of this name. */ + public String toString() { + return string; + } + + //######################################################################## + // Private Methods & Functions + + /** Is this name's ASCII representations equal to given one? */ + private boolean equals(byte[] bytes, int start, int count) { + if (ascii.length != count) return false; + for (int i = 0; i < count; i++) + if (ascii[i] != bytes[start + i]) return false; + return true; + } + + /** Returns the hash code of the ASCII representation. */ + private static int hashValue(byte[] bytes, int start, int count) { + if (count <= 0) return 0; + return count * (41 * 41 * 41) + + bytes[start] * (41 * 41) + + bytes[start + count - 1] * 41 + + bytes[start + (count >> 1)]; + } + + /** Turns the ASCII representation into a string. */ + private static String toString(byte[] bytes, int start, int count) { + return SourceRepresentation.ascii2string(bytes, start, count); + } + + //######################################################################## +} diff --git a/sources/scalac/util/TypeName.java b/sources/scalac/util/TypeName.java new file mode 100644 index 0000000000..cfe3b5193f --- /dev/null +++ b/sources/scalac/util/TypeName.java @@ -0,0 +1,36 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scalac.util; + +/** Instances of this class represent type names. */ +public final class TypeName extends Name { + + //######################################################################## + // Protected Constructors + + /** Initializes this instance. */ + protected TypeName(TermName term) { + super(term.index + 1, term); + } + + //######################################################################## + // Public Factories + + /** Returns the type name with given ASCII representation. */ + public static TypeName fromAscii(byte[] bytes, int start, int count) { + return TermName.fromAscii(bytes, start, count).toTypeName(); + } + + /** Returns the type name with given string representation. */ + public static TypeName fromString(String string) { + return TermName.fromString(string).toTypeName(); + } + + //######################################################################## +} |