summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/reify/utils/NodePrinters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/library/scala/reflect/base/Names.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Names.scala23
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala7
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala2
-rw-r--r--test/files/neg/reflection-names-neg.check10
-rw-r--r--test/files/neg/reflection-names-neg.scala6
-rw-r--r--test/files/run/reflection-names.check4
-rw-r--r--test/files/run/reflection-names.scala15
12 files changed, 73 insertions, 21 deletions
diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
index 7214da597e..6394e1eac2 100644
--- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
@@ -42,7 +42,7 @@ trait NodePrinters {
val buf = new collection.mutable.ListBuffer[String]
val annotations = m.group(3)
- if (buf.nonEmpty || annotations.nonEmpty)
+ if (buf.nonEmpty || annotations != "")
buf.append("List(" + annotations + ")")
val privateWithin = "" + m.group(2)
diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
index a3f6726b44..c79248e1c1 100644
--- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
@@ -92,7 +92,7 @@ trait ScratchPadMaker { self: Global =>
case PackageDef(_, _) =>
super.traverse(tree)
case ModuleDef(_, name, Template(_, _, body)) =>
- if (objectName.length == 0 /* objectName.isEmpty does not compile on Java 5 due to ambiguous implicit conversions: augmentString, stringToTermName */)
+ if (objectName.length == 0)
objectName = tree.symbol.fullName
body foreach traverseStat
applyPendingPatches(skipped)
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index e54ecdd590..c5092aa057 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -35,8 +35,6 @@ abstract class TypeParser {
protected var busy: Boolean = false // lock to detect recursive reads
- private implicit def stringToTermName(s: String): TermName = newTermName(s)
-
private object unpickler extends UnPickler {
val global: TypeParser.this.global.type = TypeParser.this.global
}
@@ -260,8 +258,8 @@ abstract class TypeParser {
|| ntype.IsInterface /* TODO why shouldn't nested ifaces be type-parsed too? */ )
{
val loader = new loaders.MsilFileLoader(new MsilFile(ntype))
- val nclazz = statics.newClass(ntype.Name.toTypeName)
- val nmodule = statics.newModule(ntype.Name)
+ val nclazz = statics.newClass(ntype.Name)
+ val nmodule = statics.newModule(ntype.Name)
nclazz.setInfo(loader)
nmodule.setInfo(loader)
staticDefs.enter(nclazz)
@@ -311,7 +309,7 @@ abstract class TypeParser {
assert(prop.PropertyType == getter.ReturnType);
val gparams: Array[ParameterInfo] = getter.GetParameters();
gparamsLength = gparams.length;
- val name: Name = if (gparamsLength == 0) prop.Name else nme.apply;
+ val name: TermName = if (gparamsLength == 0) prop.Name else nme.apply;
val flags = translateAttributes(getter);
val owner: Symbol = if (getter.IsStatic) statics else clazz;
val methodSym = owner.newMethod(name, NoPosition, flags)
@@ -333,7 +331,7 @@ abstract class TypeParser {
if(getter != null)
assert(sparams.length == gparamsLength + 1, "" + getter + "; " + setter);
- val name: Name = if (gparamsLength == 0) nme.getterToSetter(prop.Name)
+ val name: TermName = if (gparamsLength == 0) nme.getterToSetter(prop.Name)
else nme.update;
val flags = translateAttributes(setter);
val mtype = methodType(setter, definitions.UnitClass.tpe);
@@ -494,13 +492,13 @@ abstract class TypeParser {
else clrTypes.methods(methodSym) = method.asInstanceOf[MethodInfo];
}
- private def createMethod(name: Name, flags: Long, args: Array[MSILType], retType: MSILType, method: MethodInfo, statik: Boolean): Symbol = {
+ private def createMethod(name: TermName, flags: Long, args: Array[MSILType], retType: MSILType, method: MethodInfo, statik: Boolean): Symbol = {
val mtype = methodType(args, getCLSType(retType))
assert(mtype != null)
createMethod(name, flags, mtype, method, statik)
}
- private def createMethod(name: Name, flags: Long, mtype: Symbol => Type, method: MethodInfo, statik: Boolean): Symbol = {
+ private def createMethod(name: TermName, flags: Long, mtype: Symbol => Type, method: MethodInfo, statik: Boolean): Symbol = {
val methodSym: Symbol = (if (statik) statics else clazz).newMethod(name)
methodSym.setFlag(flags).setInfo(mtype(methodSym))
(if (statik) staticDefs else instanceDefs).enter(methodSym)
@@ -541,7 +539,7 @@ abstract class TypeParser {
s = createMethod(nme.MINUS, flags, args, typ, clrTypes.DELEGATE_REMOVE, false);
}
- private def getName(method: MethodBase): Name = {
+ private def getName(method: MethodBase): TermName = {
def operatorOverload(name : String, paramsArity : Int) : Option[Name] = paramsArity match {
case 1 => name match {
@@ -653,7 +651,7 @@ abstract class TypeParser {
private def getClassType(typ: MSILType): Type = {
assert(typ != null);
- val res = rootMirror.getClassByName(typ.FullName.replace('+', '.')).tpe;
+ val res = rootMirror.getClassByName(typ.FullName.replace('+', '.') : TypeName).tpe;
//if (res.isError())
// global.reporter.error("unknown class reference " + type.FullName);
res
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ccd346e72d..c675167139 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4283,7 +4283,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
def convertToAssignment(fun: Tree, qual: Tree, name: Name, args: List[Tree]): Tree = {
- val prefix = name stripSuffix nme.EQL
+ val prefix = name.toTermName stripSuffix nme.EQL
def mkAssign(vble: Tree): Tree =
Assign(
vble,
diff --git a/src/library/scala/reflect/base/Names.scala b/src/library/scala/reflect/base/Names.scala
index edf2ba7dc9..280a6ce8a2 100644
--- a/src/library/scala/reflect/base/Names.scala
+++ b/src/library/scala/reflect/base/Names.scala
@@ -11,6 +11,9 @@ package base
* `name1 == name2` implies `name1 eq name2`.
*/
trait Names {
+ /** Intentionally no implicit from String => Name. */
+ implicit def stringToTermName(s: String): TermName = newTermName(s)
+ implicit def stringToTypeName(s: String): TypeName = newTypeName(s)
/** The abstract type of names */
type Name >: Null <: NameBase
diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala
index 18671871ae..3c0848f77f 100644
--- a/src/reflect/scala/reflect/internal/Names.scala
+++ b/src/reflect/scala/reflect/internal/Names.scala
@@ -10,12 +10,18 @@ import scala.io.Codec
import java.security.MessageDigest
import language.implicitConversions
+trait LowPriorityNames {
+ self: Names =>
+
+ implicit def nameToNameOps(name: Name): NameOps[Name] = new NameOps[Name](name)
+}
+
/** The class Names ...
*
* @author Martin Odersky
* @version 1.0, 05/02/2005
*/
-trait Names extends api.Names {
+trait Names extends api.Names with LowPriorityNames {
implicit def promoteTermNamesAsNecessary(name: Name): TermName = name.toTermName
// Operations -------------------------------------------------------------
@@ -356,11 +362,6 @@ trait Names extends api.Names {
final def endsWith(char: Char): Boolean = len > 0 && endChar == char
final def endsWith(name: String): Boolean = endsWith(newTermName(name))
- def dropRight(n: Int): ThisNameType = subName(0, len - n)
- def drop(n: Int): ThisNameType = subName(n, len)
- def stripSuffix(suffix: Name): ThisNameType =
- if (this endsWith suffix) dropRight(suffix.length) else thisName
-
def indexOf(ch: Char) = {
val idx = pos(ch)
if (idx == length) -1 else idx
@@ -429,6 +430,16 @@ trait Names extends api.Names {
def debugString = { val s = decode ; if (isTypeName) s + "!" else s }
}
+ implicit def TermNameOps(name: TermName): NameOps[TermName] = new NameOps(name)
+ implicit def TypeNameOps(name: TypeName): NameOps[TypeName] = new NameOps(name)
+
+ final class NameOps[T <: Name](name: T) {
+ def stripSuffix(suffix: Name): T = if (name endsWith suffix) dropRight(suffix.length) else name
+ def dropRight(n: Int): T = name.subName(0, name.length - n).asInstanceOf[T]
+ def drop(n: Int): T = name.subName(n, name.length).asInstanceOf[T]
+ def nonEmpty: Boolean = name.length > 0
+ }
+
implicit val NameTag = ClassTag[Name](classOf[Name])
/** A name that contains no operator chars nor dollar signs.
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 72a99589d5..4070ad83c6 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -84,6 +84,9 @@ trait StdNames {
abstract class CommonNames extends NamesApi {
type NameType >: Null <: Name
+ // Masking some implicits so as to allow our targeted => NameType.
+ protected val stringToTermName = null
+ protected val stringToTypeName = null
protected implicit def createNameType(name: String): NameType
def flattenedName(segments: Name*): NameType =
@@ -963,7 +966,7 @@ trait StdNames {
case -1 => if (name == "") scala.Nil else scala.List(mkName(name, assumeTerm))
// otherwise, we can tell based on whether '#' or '.' is the following char.
case idx =>
- val (simple, div, rest) = (name take idx, name charAt idx, newTermName(name) drop (idx + 1))
+ val (simple, div, rest) = (name take idx, name charAt idx, name drop idx + 1)
mkName(simple, div == '.') :: segments(rest, assumeTerm)
}
}
@@ -1038,6 +1041,8 @@ trait StdNames {
}
abstract class SymbolNames {
+ protected val stringToTermName = null
+ protected val stringToTypeName = null
protected implicit def createNameType(s: String): TypeName = newTypeNameCached(s)
val BeanProperty : TypeName
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 41955170bd..e147046410 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -658,7 +658,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
val ownerModule: ModuleSymbol =
if (split > 0) packageNameToScala(fullname take split) else this.RootPackage
val owner = ownerModule.moduleClass
- val name = newTermName(fullname drop (split + 1))
+ val name = (fullname: TermName) drop split + 1
val opkg = owner.info decl name
if (opkg.isPackage)
opkg.asModuleSymbol
diff --git a/test/files/neg/reflection-names-neg.check b/test/files/neg/reflection-names-neg.check
new file mode 100644
index 0000000000..a56a19e7fd
--- /dev/null
+++ b/test/files/neg/reflection-names-neg.check
@@ -0,0 +1,10 @@
+reflection-names-neg.scala:5: error: type mismatch;
+ found : String("abc")
+ required: reflect.runtime.universe.Name
+Note that implicit conversions are not applicable because they are ambiguous:
+ both method stringToTermName in trait Names of type (s: String)reflect.runtime.universe.TermName
+ and method stringToTypeName in trait Names of type (s: String)reflect.runtime.universe.TypeName
+ are possible conversion functions from String("abc") to reflect.runtime.universe.Name
+ val x2 = ("abc": Name) drop 1 // error
+ ^
+one error found
diff --git a/test/files/neg/reflection-names-neg.scala b/test/files/neg/reflection-names-neg.scala
new file mode 100644
index 0000000000..7283d16db9
--- /dev/null
+++ b/test/files/neg/reflection-names-neg.scala
@@ -0,0 +1,6 @@
+import scala.reflect.runtime.universe._
+
+object Test {
+ val x1 = "abc" drop 1 // "bc": String
+ val x2 = ("abc": Name) drop 1 // error
+}
diff --git a/test/files/run/reflection-names.check b/test/files/run/reflection-names.check
new file mode 100644
index 0000000000..f8cb78cc67
--- /dev/null
+++ b/test/files/run/reflection-names.check
@@ -0,0 +1,4 @@
+(java.lang.String,bc)
+(scala.reflect.internal.Names$TermName_R,bc)
+(scala.reflect.internal.Names$TypeName_R,bc)
+(scala.reflect.internal.Names$TypeName_R,bc)
diff --git a/test/files/run/reflection-names.scala b/test/files/run/reflection-names.scala
new file mode 100644
index 0000000000..2433c84813
--- /dev/null
+++ b/test/files/run/reflection-names.scala
@@ -0,0 +1,15 @@
+import scala.tools.nsc._
+
+object Test {
+ val global = new Global(new Settings())
+ import global._
+
+ val x1 = "abc" drop 1 // "bc": String
+ val x2 = ("abc": TermName) drop 1 // "bc": TermName
+ val x3 = ("abc": TypeName) drop 1 // "bc": TypeName
+ val x4 = (("abc": TypeName): Name) drop 1 // "bc": Name
+
+ def main(args: Array[String]): Unit = {
+ List(x1, x2, x3, x4) foreach (x => println(x.getClass.getName, x))
+ }
+}