diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index d1309f2a1ac8..515d1a935752 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -338,13 +338,14 @@ self => /** Are we inside the Scala package? Set for files that start with package scala */ - private var inScalaPackage = false - private var currentPackage = "" + private var packageStack: List[Tree] = Nil def resetPackage(): Unit = { - inScalaPackage = false - currentPackage = "" + packageStack = Nil + } + private def inScalaRootPackage = packageStack match { + case Ident(nme.scala_) :: Nil => true + case _ => false } - private def inScalaRootPackage = inScalaPackage && currentPackage == "scala" def parseStartRule: () => Tree @@ -1294,14 +1295,10 @@ self => } /** Calls `qualId()` and manages some package state. */ private def pkgQualId() = { - if (in.token == IDENTIFIER && in.name.encode == nme.scala_) - inScalaPackage = true - val pkg = qualId() newLineOptWhenFollowedBy(LBRACE) - if (currentPackage == "") currentPackage = pkg.toString - else currentPackage = currentPackage + "." + pkg + packageStack ::= pkg pkg } @@ -3351,6 +3348,8 @@ self => } else { in.flushDoc val pkg = pkgQualId() + val saved = packageStack + packageStack ::= pkg if (in.token == EOF) { ts += makePackaging(start, pkg, List()) @@ -3362,6 +3361,7 @@ self => acceptStatSepOpt() ts ++= topStatSeq() } + packageStack = saved } } else { ts ++= topStatSeq() diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala index 2072b792004e..8fc5f003bb44 100644 --- a/src/library/scala/reflect/NameTransformer.scala +++ b/src/library/scala/reflect/NameTransformer.scala @@ -67,23 +67,35 @@ object NameTransformer { * @return the string with all recognized opchars replaced with their encoding */ def encode(name: String): String = { - var buf: StringBuilder = null + encode(name: CharSequence) match { + case s: String => s + case sb: java.lang.StringBuilder => sb.toString + } + } + + /** Replace operator symbols by corresponding `\$opname`. + * + * @param name the text to encode + * @return the text with all recognized opchars replaced with their encoding + */ + def encode(name: CharSequence): CharSequence /* String | java.lang.StringBuilder */ = { + var buf: java.lang.StringBuilder = null val len = name.length() var i = 0 while (i < len) { val c = name charAt i if (c < nops && (op2code(c.toInt) ne null)) { if (buf eq null) { - buf = new StringBuilder() - buf.append(name.substring(0, i)) + buf = new java.lang.StringBuilder() + buf.append(name.subSequence(0, i)) } buf.append(op2code(c.toInt)) /* Handle glyphs that are not valid Java/JVM identifiers */ } else if (!Character.isJavaIdentifierPart(c)) { if (buf eq null) { - buf = new StringBuilder() - buf.append(name.substring(0, i)) + buf = new java.lang.StringBuilder() + buf.append(name.subSequence(0, i)) } buf.append("$u%04X".format(c.toInt)) } @@ -92,7 +104,7 @@ object NameTransformer { } i += 1 } - if (buf eq null) name else buf.toString() + if (buf eq null) name else buf } /** Replace `\$opname` by corresponding operator symbol. diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index 146c123639e3..b7bdebd0d595 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -446,9 +446,8 @@ trait Names extends api.Names { /** Replace operator symbols by corresponding \$op_name. */ def encode: ThisNameType = { - val str = toString - val res = NameTransformer.encode(str) - if (res == str) thisName else newName(res) + val res = NameTransformer.encode(this) + if (res eq this) thisName else newName(res.toString) } /** Replace \$op_name by corresponding operator symbol. */ @@ -521,12 +520,18 @@ trait Names extends api.Names { /** TermName_S and TypeName_S have fields containing the string version of the name. * TermName_R and TypeName_R recreate it each time toString is called. */ - private final class TermName_S(index0: Int, len0: Int, next0: TermName, override val toString: String) extends TermName(index0, len0, next0) { - protected def createCompanionName(next: TypeName): TypeName = new TypeName_S(index, len, next, toString) + private final class TermName_S(index0: Int, len0: Int, next0: TermName, cachedString: String) extends TermName(index0, len0, next0) { + protected def createCompanionName(next: TypeName): TypeName = new TypeName_S(index, len, next, cachedString) override def newName(str: String): TermName = newTermNameCached(str) + override def toString: String = { + cachedString + } } - private final class TypeName_S(index0: Int, len0: Int, next0: TypeName, override val toString: String) extends TypeName(index0, len0, next0) { + private final class TypeName_S(index0: Int, len0: Int, next0: TypeName, cachedString: String) extends TypeName(index0, len0, next0) { override def newName(str: String): TypeName = newTypeNameCached(str) + override def toString: String = { + cachedString + } } private final class TermName_R(index0: Int, len0: Int, next0: TermName) extends TermName(index0, len0, next0) {