summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/internal
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-12-24 23:13:58 -0800
committerPaul Phillips <paulp@improving.org>2011-12-25 00:53:00 -0800
commita31e4f8a75f9162ab2f0c8d3bec42675b29fefb5 (patch)
tree2d7dc5d7cb35b3ea5d667cdc15edcaaab2a73f06 /src/compiler/scala/reflect/internal
parent8834d3c191e37dfa31ae11605596ce2b641ea083 (diff)
downloadscala-a31e4f8a75f9162ab2f0c8d3bec42675b29fefb5.tar.gz
scala-a31e4f8a75f9162ab2f0c8d3bec42675b29fefb5.tar.bz2
scala-a31e4f8a75f9162ab2f0c8d3bec42675b29fefb5.zip
Optimizing at the Name/String boundary.
Working on reducing the now significant amount of both garbage and retained but duplicated Strings taking place as Names become Strings and vice versa. Long way to go.
Diffstat (limited to 'src/compiler/scala/reflect/internal')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala4
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala22
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala15
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala63
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala4
5 files changed, 73 insertions, 35 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 6ee9347aab..15f89e1382 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -692,10 +692,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
result
}
+ def getClassIfDefined(fullname: String): Symbol =
+ getClassIfDefined(newTypeName(fullname))
def getClassIfDefined(fullname: Name): Symbol =
try getClass(fullname.toTypeName)
catch { case _: MissingRequirementError => NoSymbol }
+ def getModuleIfDefined(fullname: String): Symbol =
+ getModuleIfDefined(newTermName(fullname))
def getModuleIfDefined(fullname: Name): Symbol =
try getModule(fullname.toTermName)
catch { case _: MissingRequirementError => NoSymbol }
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index 01a93c0ada..d4aa6339ff 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -22,7 +22,10 @@ trait NameManglers {
val MODULE_SUFFIX_STRING = NameTransformer.MODULE_SUFFIX_STRING
val NAME_JOIN_STRING = NameTransformer.NAME_JOIN_STRING
-
+
+ val MODULE_SUFFIX_NAME: TermName = MODULE_SUFFIX_STRING
+ val NAME_JOIN_NAME: TermName = NAME_JOIN_STRING
+
def flattenedName(segments: Name*): NameType = compactedString(segments mkString NAME_JOIN_STRING)
/**
@@ -74,8 +77,11 @@ trait NameManglers {
val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set"
val SETTER_SUFFIX = encode("_=")
val SINGLETON_SUFFIX = ".type"
+ val SPECIALIZED_SUFFIX_STRING = "$sp"
val SUPER_PREFIX_STRING = "super$"
val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
+
+ val SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX_STRING
def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX
@@ -88,7 +94,7 @@ trait NameManglers {
def isSetterName(name: Name) = name endsWith SETTER_SUFFIX
def isTraitSetterName(name: Name) = isSetterName(name) && (name containsName TRAIT_SETTER_SEPARATOR_STRING)
def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX
- def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_STRING
+ def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME
def isOpAssignmentName(name: Name) = name match {
case raw.NE | raw.LE | raw.GE | EMPTY => false
@@ -112,6 +118,12 @@ trait NameManglers {
name.subName(i, name.length)
} else name
}
+
+ def unspecializedName(name: Name): Name = (
+ if (name endsWith SPECIALIZED_SUFFIX_NAME)
+ name.subName(0, name.lastIndexOf('m') - 1)
+ else name
+ )
/** Return the original name and the types on which this name
* is specialized. For example,
@@ -123,8 +135,8 @@ trait NameManglers {
* and another one belonging to the enclosing class, on Double.
*/
def splitSpecializedName(name: Name): (Name, String, String) =
- if (name.endsWith("$sp")) {
- val name1 = name stripEnd "$sp"
+ if (name endsWith SPECIALIZED_SUFFIX_NAME) {
+ val name1 = name stripEnd SPECIALIZED_SUFFIX_NAME
val idxC = name1 lastIndexOf 'c'
val idxM = name1 lastIndexOf 'm'
@@ -138,6 +150,8 @@ trait NameManglers {
def getterToLocal(name: TermName): TermName = name.toTermName append LOCAL_SUFFIX_STRING
def getterToSetter(name: TermName): TermName = name.toTermName append SETTER_SUFFIX
def localToGetter(name: TermName): TermName = name stripEnd LOCAL_SUFFIX_STRING toTermName
+
+ def dropLocalSuffix(name: Name): Name = if (name endsWith ' ') name dropRight 1 else name
def setterToGetter(name: TermName): TermName = {
val p = name.pos(TRAIT_SETTER_SEPARATOR_STRING)
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index a6fd2adb34..11be9c80d1 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -306,6 +306,16 @@ trait Names extends api.Names {
while (start <= last && !startsWith(subname, start)) start += 1
start <= last
}
+ final def containsChar(ch: Char): Boolean = {
+ var i = index
+ val max = index + len
+ while (i < max) {
+ if (chrs(i) == ch)
+ return true
+ i += 1
+ }
+ false
+ }
/** Some thoroughly self-explanatory convenience functions. They
* assume that what they're being asked to do is known to be valid.
@@ -320,6 +330,8 @@ trait Names extends api.Names {
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 dropRight(n: Int) = subName(0, len - n)
def lastIndexOf(ch: Char) = toChars lastIndexOf ch
@@ -349,6 +361,7 @@ trait Names extends api.Names {
else newTermName(res)
}
+ def append(ch: Char): Name
def append(suffix: String): Name
def append(suffix: Name): Name
@@ -377,6 +390,7 @@ trait Names extends api.Names {
n = new TypeName(index, len, h);
n
}
+ def append(ch: Char): TermName = append("" + ch)
def append(suffix: String): TermName = newTermName(this + suffix)
def append(suffix: Name): TermName = append(suffix.toString)
def companionName: TypeName = toTypeName
@@ -400,6 +414,7 @@ trait Names extends api.Names {
}
def toTypeName: TypeName = this
+ def append(ch: Char): TypeName = append("" + ch)
def append(suffix: String): TypeName = newTypeName(this + suffix)
def append(suffix: Name): TypeName = append(suffix.toString)
def companionName: TermName = toTermName
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index bc0c81a54b..0c57f0c43a 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -756,7 +756,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** If this symbol has an expanded name, its original name, otherwise its name itself.
* @see expandName
*/
- def originalName = nme.originalName(name)
+ def originalName: Name = nme.originalName(name)
/** The name of the symbol before decoding, e.g. `\$eq\$eq` instead of `==`.
*/
@@ -764,20 +764,28 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The decoded name of the symbol, e.g. `==` instead of `\$eq\$eq`.
*/
- def decodedName: String = stripNameString(NameTransformer.decode(encodedName))
+ def decodedName: String = nme.dropLocalSuffix(name).decode
- /** Either "$" or "" depending on whether this is a module class.
- */
+ private def addModuleSuffix(n: Name): Name =
+ if (needsModuleSuffix) n append nme.MODULE_SUFFIX_STRING else n
+
def moduleSuffix: String = (
- if (hasModuleFlag && !isMethod && !isImplClass && !isJavaDefined) nme.MODULE_SUFFIX_STRING
+ if (needsModuleSuffix) nme.MODULE_SUFFIX_STRING
else ""
)
-
+ /** Whether this symbol needs nme.MODULE_SUFFIX_STRING (aka $) appended on the java platform.
+ */
+ def needsModuleSuffix = (
+ hasModuleFlag
+ && !isMethod
+ && !isImplClass
+ && !isJavaDefined
+ )
/** These should be moved somewhere like JavaPlatform.
*/
- def javaSimpleName = ("" + simpleName).trim + moduleSuffix
- def javaBinaryName = fullNameInternal('/') + moduleSuffix
- def javaClassName = fullNameInternal('.') + moduleSuffix
+ def javaSimpleName: String = addModuleSuffix(nme.dropLocalSuffix(simpleName)).toString
+ def javaBinaryName: String = addModuleSuffix(fullNameInternal('/')).toString
+ def javaClassName: String = addModuleSuffix(fullNameInternal('.')).toString
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by `separator` characters.
@@ -785,23 +793,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* Never adds id.
* Drops package objects.
*/
- final def fullName(separator: Char): String = stripNameString(fullNameInternal(separator))
+ final def fullName(separator: Char): String = nme.dropLocalSuffix(fullNameInternal(separator)).toString
/** Doesn't drop package objects, for those situations (e.g. classloading)
* where the true path is needed.
*/
- private def fullNameInternal(separator: Char): String = (
- if (isRoot || isRootPackage || this == NoSymbol) this.toString
- else if (owner.isEffectiveRoot) encodedName
- else effectiveOwner.enclClass.fullName(separator) + separator + encodedName
+ private def fullNameInternal(separator: Char): Name = (
+ if (isRoot || isRootPackage || this == NoSymbol) name
+ else if (owner.isEffectiveRoot) name
+ else effectiveOwner.enclClass.fullName(separator) append separator append name
)
- /** Strip package objects and any local suffix.
- */
- private def stripNameString(s: String) =
- if (settings.debug.value) s
- else s stripSuffix nme.LOCAL_SUFFIX_STRING
-
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by periods.
*/
@@ -1702,7 +1704,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def getter(base: Symbol): Symbol = base.info.decl(getterName) filter (_.hasAccessorFlag)
- def getterName = (
+ def getterName: Name = (
if (isSetter) nme.setterToGetter(name)
else if (nme.isLocalName(name)) nme.localToGetter(name)
else name
@@ -1800,7 +1802,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ toString -------------------------------------------------------------------
/** A tag which (in the ideal case) uniquely identifies class symbols */
- final def tag = fullName.##
+ final def tag: Int = fullName.##
/** The simple name of this Symbol */
final def simpleName: Name = name
@@ -1810,7 +1812,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* (the initial Name) before falling back on id, which varies depending
* on exactly when a symbol is loaded.
*/
- final def sealedSortName = initName + "#" + id
+ final def sealedSortName: String = initName + "#" + id
/** String representation of symbol's definition key word */
final def keyString: String =
@@ -1878,7 +1880,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* E.g. $eq => =.
* If settings.uniqid, adds id.
*/
- def nameString = decodedName + idString
+ def nameString: String = (
+ if (settings.uniqid.value) decodedName + "#" + id
+ else "" + decodedName
+ )
/** If settings.uniqid is set, the symbol's id, else "" */
final def idString = if (settings.uniqid.value) "#"+id else ""
@@ -1886,14 +1891,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation, including symbol's kind e.g., "class Foo", "method Bar".
* If hasMeaninglessName is true, uses the owner's name to disambiguate identity.
*/
- override def toString = compose(
+ override def toString: String = compose(
kindString,
if (hasMeaninglessName) owner.decodedName + idString else nameString
)
/** String representation of location.
*/
- def ownsString = {
+ def ownsString: String = {
val owns = effectiveOwner
if (owns.isClass && !owns.isEmptyPrefix) "" + owns else ""
}
@@ -1901,12 +1906,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation of location, plus a preposition. Doesn't do much,
* for backward compatibility reasons.
*/
- def locationString = ownsString match {
+ def locationString: String = ownsString match {
case "" => ""
case s => " in " + s
}
- def fullLocationString = toString + locationString
- def signatureString = if (hasRawInfo) infoString(rawInfo) else "<_>"
+ def fullLocationString: String = toString + locationString
+ def signatureString: String = if (hasRawInfo) infoString(rawInfo) else "<_>"
/** String representation of symbol's definition following its name */
final def infoString(tp: Type): String = {
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index d17747e22a..2db957410b 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -5713,7 +5713,7 @@ A type's typeSymbol should never be inspected directly.
}
val res = lub0(ts)
if (printLubs) {
- indent = indent dropRight 2
+ indent = indent stripSuffix " "
println(indent + "lub of " + ts + " is " + res)//debug
}
if (ts forall (_.isNotNull)) res.notNull else res
@@ -6172,7 +6172,7 @@ A type's typeSymbol should never be inspected directly.
Console.println(indent + tp1 + " " + op + " " + arg2 + "?" /* + "("+tp1.getClass+","+arg2.getClass+")"*/)
indent = indent + " "
val result = p(tp1, arg2)
- indent = indent dropRight 2
+ indent = indent stripSuffix " "
Console.println(indent + result)
result
}