summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala4
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala15
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala6
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala15
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala17
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala12
-rw-r--r--src/compiler/scala/tools/nsc/dependencies/Changes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ByteCode.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala7
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala10
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala63
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/util/Origins.scala4
-rw-r--r--src/library/scala/Enumeration.scala9
-rwxr-xr-xsrc/library/scala/reflect/NameTransformer.scala6
23 files changed, 138 insertions, 84 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index e1a3e732b0..00d2c232a0 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -765,8 +765,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
def flatNameString(sym: Symbol, separator: Char): String =
if (sym == NoSymbol) "" // be more resistant to error conditions, e.g. neg/t3222.scala
- else if (sym.owner.isPackageClass) sym.fullName('.') + (if (sym.isModuleClass) "$" else "")
- else flatNameString(sym.owner, separator) + "$" + sym.simpleName;
+ else if (sym.owner.isPackageClass) sym.javaClassName
+ else flatNameString(sym.owner, separator) + nme.NAME_JOIN_STRING + sym.simpleName
def signature1(etp: Type): String = {
if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head))
else if (isValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString()
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index 571b2ba248..c09397e2c2 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -20,7 +20,10 @@ trait NameManglers {
trait NameManglingCommon {
self: CommonNames =>
- def flattenedName(segments: Name*): NameType = compactedString(segments mkString "$")
+ val MODULE_SUFFIX_STRING = NameTransformer.MODULE_SUFFIX_STRING
+ val NAME_JOIN_STRING = NameTransformer.NAME_JOIN_STRING
+
+ def flattenedName(segments: Name*): NameType = compactedString(segments mkString NAME_JOIN_STRING)
/**
* COMPACTIFY
@@ -66,12 +69,12 @@ trait NameManglers {
self: nme.type =>
val IMPL_CLASS_SUFFIX = "$class"
- val SINGLETON_SUFFIX = ".type"
val LOCALDUMMY_PREFIX = "<local " // owner of local blocks
val PROTECTED_PREFIX = "protected$"
val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set"
val SELECTOR_DUMMY = "<unapply-selector>"
val SETTER_SUFFIX = encode("_=")
+ val SINGLETON_SUFFIX = ".type"
val SUPER_PREFIX_STRING = "super$"
val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
@@ -87,6 +90,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 isOpAssignmentName(name: Name) = name match {
case raw.NE | raw.LE | raw.GE | EMPTY => false
@@ -155,6 +159,13 @@ trait NameManglers {
else name
}
+ def stripModuleSuffix(name: Name): Name = (
+ if (isModuleName(name)) name stripEnd MODULE_SUFFIX_STRING else name
+ )
+
+ /** Note that for performance reasons, stripEnd does not verify that the
+ * suffix is actually the suffix specified.
+ */
def dropSingletonName(name: Name): TypeName = name stripEnd SINGLETON_SUFFIX toTypeName
def singletonName(name: Name): TypeName = name append SINGLETON_SUFFIX toTypeName
def implClassName(name: Name): TypeName = name append IMPL_CLASS_SUFFIX toTypeName
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 43fe89ed63..4947334c1e 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -92,7 +92,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val ANON_FUN_NAME: NameType = "$anonfun"
val EMPTY_PACKAGE_NAME: NameType = "<empty>"
val IMPORT: NameType = "<import>"
- val MODULE_SUFFIX: NameType = "$module"
+ val MODULE_VAR_SUFFIX: NameType = "$module"
val ROOT: NameType = "<root>"
// value types are all used as terms as well
@@ -172,7 +172,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val FAKE_LOCAL_THIS: NameType = "this$"
val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something?
val MIXIN_CONSTRUCTOR: NameType = "$init$"
- val MODULE_INSTANCE_FIELD: NameType = "MODULE$"
+ val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
val OUTER: NameType = "$outer"
val OUTER_LOCAL: NameType = "$outer " // note the space
val SELF: NameType = "$this"
@@ -374,7 +374,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName =
newTermName(base.fullName('$') + separator + name)
- def moduleVarName(name: TermName): TermName = newTermName("" + name + MODULE_SUFFIX)
+ def moduleVarName(name: TermName): TermName = newTermName("" + name + MODULE_VAR_SUFFIX)
val EXPAND_SEPARATOR_STRING = "$$"
val LOCAL_SUFFIX_STRING = " "
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index f9afd164f5..91f052af6c 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -620,6 +620,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
def ownerChain: List[Symbol] = this :: owner.ownerChain
+ def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain
+
def enclClassChain: List[Symbol] = {
if (this eq NoSymbol) Nil
else if (isClass && !isPackageClass) this :: owner.enclClassChain
@@ -665,7 +667,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def originalName = nme.originalName(name)
- /** The name of the symbol before decoding, e.g. `\$eq\$eq` instead of `==`.
+ /** The name of the symbol before decoding, e.g. `\$eq\$eq` instead of `==`.
*/
def encodedName: String = name.toString
@@ -673,6 +675,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def decodedName: String = stripLocalSuffix(NameTransformer.decode(encodedName))
+ def moduleSuffix: String = (
+ if (hasModuleFlag && !isMethod && !isImplClass && !isJavaDefined) nme.MODULE_SUFFIX_STRING
+ else ""
+ )
+
+ /** These should be moved somewhere like JavaPlatform.
+ */
+ def javaSimpleName = stripLocalSuffix("" + simpleName) + moduleSuffix
+ def javaBinaryName = fullName('/') + moduleSuffix
+ def javaClassName = fullName('.') + moduleSuffix
+
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by `separator` characters.
* Never translates expansions of operators back to operator symbol.
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index a53fbef200..7c382c5f93 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -95,12 +95,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
}
- /** Return the suffix of a class name */
- def moduleSuffix(sym: Symbol) =
- if (sym.hasModuleFlag && !sym.isMethod &&
- !sym.isImplClass && !sym.isJavaDefined) "$"
- else ""
-
var pickledBytes = 0 // statistics
/**
@@ -161,8 +155,13 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val emitVars = debugLevel >= 3
override def javaName(sym: Symbol): String = {
- if (sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass)
+ val isInner = sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass
+ // TODO: something atPhase(currentRun.flattenPhase.prev) which accounts for
+ // being nested in parameterized classes (if we're going to selectively flatten.)
+ if (isInner) {
+ log("Inner class: " + sym.fullLocationString)
innerClassBuffer += sym
+ }
super.javaName(sym)
}
@@ -199,7 +198,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
*/
def scalaSignatureAddingMarker(jclass: JClass, sym: Symbol): Option[AnnotationInfo] =
currentRun.symData get sym match {
- case Some(pickle) if !jclass.getName().endsWith("$") =>
+ case Some(pickle) if !nme.isModuleName(jclass.getName()) =>
val scalaAttr =
fjbgContext.JOtherAttribute(jclass, jclass, tpnme.ScalaSignatureATTR.toString,
versionPickle.bytes, versionPickle.writeIndex)
@@ -673,7 +672,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
null
else {
val outerName = javaName(innerSym.rawowner)
- if (isTopLevelModule(innerSym.rawowner)) outerName stripSuffix "$"
+ if (isTopLevelModule(innerSym.rawowner)) "" + nme.stripModuleSuffix(outerName)
else outerName
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
index 9697477543..acaf1f6cc2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
@@ -87,9 +87,9 @@ trait GenJVMUtil {
def javaName(sym: Symbol): String =
javaNameCache.getOrElseUpdate(sym, {
if (sym.isClass || (sym.isModule && !sym.isMethod))
- sym.fullName('/') + moduleSuffix(sym)
+ sym.javaBinaryName
else
- sym.simpleName.toString.trim() + moduleSuffix(sym)
+ sym.javaSimpleName
})
def javaType(t: TypeKind): JType = (t: @unchecked) match {
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
index ae2082ec8b..f2f5ecb2fe 100644
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
@@ -1618,9 +1618,7 @@ abstract class GenMSIL extends SubComponent {
* not exist in the classpath: the type checker will be very confused.
*/
def msilName(sym: Symbol): String = {
- val suffix: String = if (sym.hasModuleFlag && !sym.isMethod &&
- !sym.isImplClass &&
- !sym.isJavaDefined) "$" else ""
+ val suffix = sym.moduleSuffix
// Flags.JAVA: "symbol was not defined by a scala-class" (java, or .net-class)
if (sym == definitions.NothingClass)
@@ -2035,7 +2033,7 @@ abstract class GenMSIL extends SubComponent {
}
def nestingAwareFullClassname(csym: Symbol) : String = {
- val suffix = moduleSuffix(csym)
+ val suffix = csym.moduleSuffix
val res = if (csym.isNestedClass)
nestingAwareFullClassname(csym.owner) + "+" + csym.encodedName
else
@@ -2043,12 +2041,6 @@ abstract class GenMSIL extends SubComponent {
res + suffix
}
- /** cut&pasted from GenJVM */
- def moduleSuffix(sym: Symbol) =
- if (sym.hasFlag(Flags.MODULE) && !sym.isMethod &&
- !sym.isImplClass && !sym.hasFlag(Flags.JAVA)) "$"
- else "";
-
/** Adds a static initializer which creates an instance of the module
* class (calls the primary constructor). A special primary constructor
* will be generated (notInitializedModules) which stores the new instance
diff --git a/src/compiler/scala/tools/nsc/dependencies/Changes.scala b/src/compiler/scala/tools/nsc/dependencies/Changes.scala
index baab0271e1..4c7263ef69 100644
--- a/src/compiler/scala/tools/nsc/dependencies/Changes.scala
+++ b/src/compiler/scala/tools/nsc/dependencies/Changes.scala
@@ -52,7 +52,7 @@ abstract class Changes {
private val changedTypeParams = new mutable.HashSet[String]
private def sameParameterSymbolNames(sym1: Symbol, sym2: Symbol): Boolean =
- sameSymbol(sym1, sym2, true) || sym2.encodedName.startsWith(sym1.encodedName + "$") // see #3140
+ sameSymbol(sym1, sym2, true) || sym2.encodedName.startsWith(sym1.encodedName + nme.NAME_JOIN_STRING) // see #3140
private def sameSymbol(sym1: Symbol, sym2: Symbol, simple: Boolean = false): Boolean =
if (simple) sym1.encodedName == sym2.encodedName else sym1.fullName == sym2.fullName
private def sameFlags(sym1: Symbol, sym2: Symbol): Boolean =
diff --git a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala
index 1b2f6443ae..ece80af272 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala
@@ -10,6 +10,7 @@ import java.lang.reflect
import java.util.concurrent.ConcurrentHashMap
import util.ScalaClassLoader
import ScalaClassLoader.getSystemLoader
+import scala.reflect.NameTransformer._
object ByteCode {
/** Until I figure out why I can't get scalap onto the classpath such
@@ -17,7 +18,7 @@ object ByteCode {
*/
private lazy val DECODER: Option[AnyRef] =
for (clazz <- getSystemLoader.tryToLoadClass[AnyRef]("scala.tools.scalap.Decode$")) yield
- clazz.getField("MODULE$").get()
+ clazz.getField(MODULE_INSTANCE_NAME).get()
private def decoderMethod(name: String, args: JClass*): Option[reflect.Method] = {
for (decoder <- DECODER ; m <- Option(decoder.getClass.getMethod(name, args: _*))) yield m
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 8e7f73296f..8ae4f9779a 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -18,6 +18,7 @@ import scala.concurrent.ops
import util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream }
import interpreter._
import io.{ File, Sources }
+import scala.reflect.NameTransformer._
/** The Scala interactive shell. It provides a read-eval-print loop
* around the Interpreter class.
@@ -359,10 +360,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
if (rest.nonEmpty) {
intp optFlatName hd match {
case Some(flat) =>
- val clazz = flat :: rest mkString "$"
+ val clazz = flat :: rest mkString NAME_JOIN_STRING
val bytes = super.tryClass(clazz)
if (bytes.nonEmpty) bytes
- else super.tryClass(clazz + "$")
+ else super.tryClass(clazz + MODULE_SUFFIX_STRING)
case _ => super.tryClass(path)
}
}
@@ -371,7 +372,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
// we have to drop the $ to find object Foo, then tack it back onto
// the end of the flattened name.
def className = intp flatName path
- def moduleName = (intp flatName path.stripSuffix("$")) + "$"
+ def moduleName = (intp flatName path.stripSuffix(MODULE_SUFFIX_STRING)) + MODULE_SUFFIX_STRING
val bytes = super.tryClass(className)
if (bytes.nonEmpty) bytes
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 9edf7f44f3..b84bf178a0 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -209,7 +209,11 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
def quietRun[T](code: String) = beQuietDuring(interpret(code))
private def logAndDiscard[T](label: String, alt: => T): PartialFunction[Throwable, T] = {
- case t => repldbg(label + ": " + t) ; alt
+ case t =>
+ repldbg(label + ": " + unwrap(t))
+ repltrace(util.stackTraceString(unwrap(t)))
+
+ alt
}
/** whether to bind the lastException variable */
@@ -311,7 +315,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
* }}}
*/
def generatedName(simpleName: String): Option[String] = {
- if (simpleName endsWith "$") optFlatName(simpleName.init) map (_ + "$")
+ if (simpleName endsWith nme.MODULE_SUFFIX_STRING) optFlatName(simpleName.init) map (_ + nme.MODULE_SUFFIX_STRING)
else optFlatName(simpleName)
}
def flatName(id: String) = optFlatName(id) getOrElse id
@@ -795,7 +799,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
* $line5.$iw$$iw$$iw$Bippy // fullFlatName
*/
def fullFlatName(name: String) =
- lineRep.readPath + accessPath.replace('.', '$') + "$" + name
+ lineRep.readPath + accessPath.replace('.', '$') + nme.NAME_JOIN_STRING + name
/** The unmangled symbol name, but supplemented with line info. */
def disambiguated(name: Name): String = name + " (in " + lineRep + ")"
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 95b42ebf69..cfef2c5e87 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -188,7 +188,7 @@ abstract class Power(
getCompilerClass("scala." + x).tpe
case _ =>
val name = m.erasure.getName
- if (name endsWith "$") getCompilerModule(name dropRight 1).tpe
+ if (name endsWith nme.MODULE_SUFFIX_STRING) getCompilerModule(name dropRight 1).tpe
else {
val sym = getCompilerClass(name)
val args = m.typeArguments
@@ -361,7 +361,7 @@ abstract class Power(
object Implicits extends Implicits2 { }
trait ReplUtilities {
- def module[T: Manifest] = getCompilerModule(manifest[T].erasure.getName stripSuffix "$")
+ def module[T: Manifest] = getCompilerModule(manifest[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING)
def clazz[T: Manifest] = getCompilerClass(manifest[T].erasure.getName)
def info[T: Manifest] = InternalInfo[T]
def ?[T: Manifest] = InternalInfo[T]
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
index fc286b4868..aa926adecc 100644
--- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -9,6 +9,7 @@ package interpreter
import java.lang.{ reflect => r }
import r.TypeVariable
import scala.reflect.NameTransformer
+import NameTransformer._
/** Logic for turning a type into a String. The goal is to be
* able to take some arbitrary object 'x' and obtain the most precise
@@ -36,17 +37,17 @@ trait TypeStrings {
} toMap
def scalaName(s: String): String = {
- if (s endsWith "$") s.init + ".type"
+ if (s endsWith MODULE_SUFFIX_STRING) s.init + ".type"
else if (s == "void") "scala.Unit"
else if (primitives(s)) "scala." + s.capitalize
- else primitiveMap.getOrElse(s, NameTransformer decode s)
+ else primitiveMap.getOrElse(s, NameTransformer.decode(s))
}
// Trying to put humpty dumpty back together again.
def scalaName(clazz: JClass): String = {
val name = clazz.getName
val isAnon = clazz.isScalaAnonymous
val enclClass = clazz.getEnclosingClass
- def enclPre = enclClass.getName + "$"
+ def enclPre = enclClass.getName + MODULE_SUFFIX_STRING
def enclMatch = name startsWith enclPre
scalaName(
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 9d3421ae27..1970a580a6 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -187,8 +187,8 @@ abstract class ClassfileParser {
val start = starts(index)
if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
val name = getExternalName(in.getChar(start + 1))
- if (name endsWith '$')
- c = definitions.getModule(name stripEnd "$")
+ if (nme.isModuleName(name))
+ c = definitions.getModule(nme.stripModuleSuffix(name))
else
c = classNameToSymbol(name)
@@ -1226,9 +1226,7 @@ abstract class ClassfileParser {
innerClasses.get(externalName) match {
case Some(entry) =>
- val outerName =
- if (entry.outerName.endsWith("$")) entry.outerName.subName(0, entry.outerName.length - 1)
- else entry.outerName
+ val outerName = nme.stripModuleSuffix(entry.outerName)
val sym = classSymbol(outerName)
val s =
// if loading during initialization of `definitions` typerPhase is not yet set.
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 1d8588209e..b9e8abe53f 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -37,15 +37,14 @@ abstract class ICodeReader extends ClassfileParser {
*/
def readClass(cls: Symbol): (IClass, IClass) = {
var classFile: io.AbstractFile = null;
- var sym = cls
- sym.info // ensure accurate type information
+ cls.info // ensure accurate type information
isScalaModule = cls.isModule && !cls.isJavaDefined
log("Reading class: " + cls + " isScalaModule?: " + isScalaModule)
- val name = cls.fullName('.') + (if (sym.hasFlag(MODULE)) "$" else "")
+ val name = cls.javaClassName
classPath.findSourceFile(name) match {
- case Some(classFile) => parse(classFile, sym)
+ case Some(classFile) => parse(classFile, cls)
case _ => throw new MissingRequirementError("Could not find bytecode for " + cls)
}
@@ -192,7 +191,7 @@ abstract class ICodeReader extends ClassfileParser {
log("forcing " + iface.owner + " at phase: " + phase + " impl: " + iface.implClass)
iface.owner.info // force the mixin type-transformer
definitions.getClass(name)
- } else if (name.endsWith("$")) {
+ } else if (name.endsWith(nme.MODULE_SUFFIX_STRING)) {
val sym = forceMangledName(name.subName(0, name.length -1).decode, true)
// println("classNameToSymbol: " + name + " sym: " + sym)
if (name.toString == "scala.collection.immutable.Stream$$hash$colon$colon$")
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index a333c7458d..eb700f1610 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -62,7 +62,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
// The constructor parameter with given name. This means the parameter
// has given name, or starts with given name, and continues with a `$` afterwards.
def parameterNamed(name: Name): Symbol = {
- def matchesName(param: Symbol) = param.name == name || param.name.startsWith(name + "$")
+ def matchesName(param: Symbol) = param.name == name || param.name.startsWith(name + nme.NAME_JOIN_STRING)
(constrParams filter matchesName) match {
case Nil => assert(false, name + " not in " + constrParams) ; null
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index fbb5a8dcde..c2013e77f9 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -214,10 +214,7 @@ abstract class Erasure extends AddInterfaces
// Anything which could conceivably be a module (i.e. isn't known to be
// a type parameter or similar) must go through here or the signature is
// likely to end up with Foo<T>.Empty where it needs Foo<T>.Empty$.
- def nameInSig(sym: Symbol) = "" + sym.name + global.genJVM.moduleSuffix(sym)
- def fullNameInSig(sym: Symbol) = "L" + (
- atPhase(currentRun.icodePhase)(sym.fullName('/') + global.genJVM.moduleSuffix(sym))
- )
+ def fullNameInSig(sym: Symbol) = "L" + atPhase(currentRun.icodePhase)(sym.javaBinaryName)
def jsig(tp0: Type, existentiallyBound: List[Symbol] = Nil, toplevel: Boolean = false, primitiveOK: Boolean = true): String = {
val tp = tp0.dealias
@@ -266,7 +263,7 @@ abstract class Erasure extends AddInterfaces
(
if (needsJavaSig(preRebound)) {
val s = jsig(preRebound, existentiallyBound)
- if (s.charAt(0) == 'L') s.substring(0, s.length - 1) + "." + nameInSig(sym)
+ if (s.charAt(0) == 'L') s.substring(0, s.length - 1) + "." + sym.javaSimpleName
else fullNameInSig(sym)
}
else fullNameInSig(sym)
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index 28dfabb035..53016dd748 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -18,43 +18,69 @@ abstract class Flatten extends InfoTransform {
/** the following two members override abstract members in Transform */
val phaseName: String = "flatten"
+ /** Updates the owning scope with the given symbol; returns the old symbol.
+ */
+ private def replaceSymbolInCurrentScope(sym: Symbol): Symbol = {
+ atPhase(phase.next) {
+ val scope = sym.owner.info.decls
+ val old = scope lookup sym.name
+ if (old ne NoSymbol)
+ scope unlink old
+
+ scope enter sym
+ old
+ }
+ }
+
private def liftClass(sym: Symbol) {
- if (!(sym hasFlag LIFTED)) {
+ if (!sym.isLifted) {
sym setFlag LIFTED
- atPhase(phase.next) {
- if (settings.debug.value) log("re-enter " + sym + " in " + sym.owner)
- assert(sym.owner.isPackageClass, sym) //debug
- val scope = sym.owner.info.decls
- val old = scope lookup sym.name
- if (old != NoSymbol) scope unlink old
- scope enter sym
- }
+ debuglog("re-enter " + sym.fullLocationString)
+ val old = replaceSymbolInCurrentScope(sym)
+ if (old ne NoSymbol)
+ debuglog("lifted " + sym.fullLocationString + ", unlinked " + old)
+ }
+ }
+ private def liftSymbol(sym: Symbol) {
+ liftClass(sym)
+ if (sym.needsImplClass)
+ liftClass(erasure implClass sym)
+ }
+ // This is a short-term measure partially working around objects being
+ // lifted out of parameterized classes, leaving them referencing
+ // invisible type parameters.
+ private def isFlattenablePrefix(pre: Type) = {
+ val clazz = pre.typeSymbol
+ clazz.isClass && !clazz.isPackageClass && {
+ // Cannot flatten here: class A[T] { object B }
+ atPhase(currentRun.erasurePhase.prev)(clazz.typeParams.isEmpty)
}
}
private val flattened = new TypeMap {
def apply(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args) if (pre.typeSymbol.isClass && !pre.typeSymbol.isPackageClass) =>
- assert(args.isEmpty)
- assert(sym.toplevelClass != NoSymbol, sym.ownerChain)
- typeRef(sym.toplevelClass.owner.thisType, sym, args)
+ case TypeRef(pre, sym, args) if isFlattenablePrefix(pre) =>
+ assert(args.isEmpty && sym.toplevelClass != NoSymbol, sym.ownerChain)
+ typeRef(sym.toplevelClass.owner.thisType, sym, Nil)
case ClassInfoType(parents, decls, clazz) =>
var parents1 = parents
val decls1 = new Scope
if (clazz.isPackageClass) {
atPhase(phase.next)(decls foreach (decls1 enter _))
- } else {
+ }
+ else {
val oldowner = clazz.owner
atPhase(phase.next)(oldowner.info)
parents1 = parents mapConserve (this)
+
for (sym <- decls) {
if (sym.isTerm && !sym.isStaticModule) {
decls1 enter sym
- if (sym.isModule) sym.moduleClass setFlag LIFTED
- } else if (sym.isClass) {
- liftClass(sym)
- if (sym.needsImplClass) liftClass(erasure.implClass(sym))
+ if (sym.isModule)
+ sym.moduleClass setFlag LIFTED
}
+ else if (sym.isClass)
+ liftSymbol(sym)
}
}
ClassInfoType(parents1, decls1, clazz)
@@ -74,7 +100,6 @@ abstract class Flatten extends InfoTransform {
protected def newTransformer(unit: CompilationUnit): Transformer = new Flattener
class Flattener extends Transformer {
-
/** Buffers for lifted out classes */
private val liftedDefs = new mutable.HashMap[Symbol, ListBuffer[Tree]]
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 7c3ace7637..533caff078 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -195,9 +195,9 @@ abstract class LambdaLift extends InfoTransform {
for (sym <- renamable) {
val originalName = sym.name
- val base = sym.name + "$" + (
+ val base = sym.name + nme.NAME_JOIN_STRING + (
if (sym.isAnonymousFunction && sym.owner.isMethod)
- sym.owner.name + "$"
+ sym.owner.name + nme.NAME_JOIN_STRING
else ""
)
sym.name =
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 9e9c42cf90..6bbb94bf29 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1259,8 +1259,8 @@ trait Namers { self: Analyzer =>
def notMember() = context.error(tree.pos, from.decode + " is not a member of " + expr)
// for Java code importing Scala objects
- if (from endsWith nme.raw.DOLLAR)
- isValidSelector(from stripEnd "$")(notMember())
+ if (nme.isModuleName(from))
+ isValidSelector(nme.stripModuleSuffix(from))(notMember())
else
notMember()
}
diff --git a/src/compiler/scala/tools/nsc/util/Origins.scala b/src/compiler/scala/tools/nsc/util/Origins.scala
index 847a9b6dad..f8ba34ae3c 100644
--- a/src/compiler/scala/tools/nsc/util/Origins.scala
+++ b/src/compiler/scala/tools/nsc/util/Origins.scala
@@ -6,6 +6,8 @@
package scala.tools.nsc
package util
+import scala.reflect.NameTransformer._
+
/** A debugging class for logging from whence a method is being called.
* Say you wanted to discover who was calling phase_= in SymbolTable.
* You could do this:
@@ -98,7 +100,7 @@ object Origins {
class OneLine(clazz: Class[_]) extends Origins {
type Rep = StackTraceElement
- val originClass = clazz.getName stripSuffix "$"
+ val originClass = clazz.getName stripSuffix MODULE_SUFFIX_STRING
def newRep(xs: StackSlice): Rep = xs(0)
def repString(rep: Rep) = " " + rep
}
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index 563b2d70c4..22bb98ba46 100644
--- a/src/library/scala/Enumeration.scala
+++ b/src/library/scala/Enumeration.scala
@@ -10,6 +10,8 @@ package scala
import scala.collection.{ mutable, immutable, generic, SetLike }
import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField }
+import scala.reflect.NameTransformer._
+import java.util.regex.Pattern
/** Defines a finite set of values specific to the enumeration. Typically
* these values enumerate all possible forms something can take and provide
@@ -59,11 +61,14 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable {
/* Note that `readResolve` cannot be private, since otherwise
the JVM does not invoke it when deserializing subclasses. */
- protected def readResolve(): AnyRef = thisenum.getClass.getField("MODULE$").get()
+ protected def readResolve(): AnyRef = thisenum.getClass.getField(MODULE_INSTANCE_NAME).get()
/** The name of this enumeration.
*/
- override def toString = (getClass.getName stripSuffix "$" split '.' last) split '$' last
+ override def toString = (
+ (getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.' last)
+ split Pattern.quote(NAME_JOIN_STRING) last
+ )
/** The mapping from the integer used to identify values to the actual
* values. */
diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala
index 6c12c8db33..38fbbc98f2 100755
--- a/src/library/scala/reflect/NameTransformer.scala
+++ b/src/library/scala/reflect/NameTransformer.scala
@@ -12,6 +12,12 @@ package scala.reflect
* @author Martin Odersky
*/
object NameTransformer {
+ // XXX Short term: providing a way to alter these without having to recompile
+ // the compiler before recompiling the compiler.
+ val MODULE_SUFFIX_STRING = sys.props.getOrElse("SCALA_MODULE_SUFFIX_STRING", "$")
+ val NAME_JOIN_STRING = sys.props.getOrElse("SCALA_NAME_JOIN_STRING", "$")
+ val MODULE_INSTANCE_NAME = "MODULE$"
+
private val nops = 128
private val ncodes = 26 * 26