summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-04-09 15:42:24 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-04-09 15:42:24 +0000
commitd76943f9ae43176980f21f90f400053fe2da3fbf (patch)
treed43b33f4cc1055f78ec2853164d61171fec17f3c
parent73648228fffb462113ebfa6222824cc229cf808c (diff)
downloadscala-d76943f9ae43176980f21f90f400053fe2da3fbf.tar.gz
scala-d76943f9ae43176980f21f90f400053fe2da3fbf.tar.bz2
scala-d76943f9ae43176980f21f90f400053fe2da3fbf.zip
Companion objects of primitive types are now va...
Companion objects of primitive types are now values. Term 'scala.Int' resolves in bytecode to an instance of 'scala.runtime.Int'. This is the first step towards replacing strings in @specialized with a proper list of types, so instead of @specialized("Int, Float") one will write @specialized(Int, Float). Review by odersky.
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala22
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala5
-rw-r--r--src/library/scala/runtime/AnyValCompanion.scala86
-rw-r--r--test/files/neg/bug1392.check4
-rw-r--r--test/files/neg/bug1392.scala1
-rw-r--r--test/files/neg/bug3123.check4
-rw-r--r--test/files/neg/bug3123.scala5
9 files changed, 115 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index b1d1849c71..a3b81862e6 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -807,14 +807,17 @@ abstract class GenICode extends SubComponent {
ctx
case Select(qualifier, selector) =>
- val sym = tree.symbol
+ var sym = tree.symbol
generatedType = toTypeKind(sym.info)
if (sym.isModule) {
if (settings.debug.value)
log("LOAD_MODULE from Select(qualifier, selector): " + sym);
assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- ctx.bb.emit(LOAD_MODULE(sym), tree.pos);
+ if (definitions.primitiveCompanions(sym))
+ ctx.bb.emit(LOAD_MODULE(definitions.getModule("scala.runtime." + sym.name)))
+ else
+ ctx.bb.emit(LOAD_MODULE(sym), tree.pos);
ctx
} else if (sym.isStaticMember) {
ctx.bb.emit(LOAD_FIELD(sym, true), tree.pos)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 40eb08adfd..c587b8342c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -1737,6 +1737,8 @@ abstract class GenJVM extends SubComponent {
return javaName(definitions.RuntimeNothingClass)
else if (sym == definitions.NullClass)
return javaName(definitions.RuntimeNullClass)
+ else if (definitions.primitiveCompanions(sym.companionModule))
+ return javaName(definitions.getModule("scala.runtime." + sym.name))
if (sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass) {
innerClasses = innerClasses + sym;
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 73d5193ed0..a2382063c3 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -82,8 +82,12 @@ trait Definitions extends reflect.generic.StandardDefinitions {
lazy val RuntimeNothingClass = getClass("scala.runtime.Nothing$")
lazy val RuntimeNullClass = getClass("scala.runtime.Null$")
+ lazy val AnyValCompanionClass = getClass("scala.runtime.AnyValCompanion").setFlag(SEALED | ABSTRACT | TRAIT)
+
// the scala value classes
- lazy val UnitClass = newClass(ScalaPackageClass, nme.Unit, anyvalparam).setFlag(ABSTRACT | FINAL)
+ lazy val UnitClass =
+ newClass(ScalaPackageClass, nme.Unit, anyvalparam).setFlag(ABSTRACT | FINAL)
+
lazy val ByteClass = newValueClass(nme.Byte, 'B', 2)
lazy val ShortClass = newValueClass(nme.Short, 'S', 4)
lazy val CharClass = newValueClass(nme.Char, 'C', 3)
@@ -578,6 +582,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
val boxedModule = new HashMap[Symbol, Symbol]
val unboxMethod = new HashMap[Symbol, Symbol] // Type -> Method
val boxMethod = new HashMap[Symbol, Symbol] // Type -> Method
+ val primitiveCompanions = new HashSet[Symbol]
def isUnbox(m: Symbol) = unboxMethod.valuesIterator contains m
def isBox(m: Symbol) = boxMethod.valuesIterator contains m
@@ -596,6 +601,17 @@ trait Definitions extends reflect.generic.StandardDefinitions {
case None => false
}
+ /** Create a companion object for scala.Unit.
+ */
+ private def initUnitCompanionObject() {
+ val module = ScalaPackageClass.newModule(NoPosition, "Unit")
+ ScalaPackageClass.info.decls.enter(module)
+ val mclass = module.moduleClass
+ mclass.setInfo(ClassInfoType(List(AnyRefClass.tpe, AnyValCompanionClass.tpe), new Scope, mclass))
+ module.setInfo(mclass.tpe)
+ primitiveCompanions += module
+ }
+
private[symtab] def newValueClass(name: Name, tag: Char, weight: Int): Symbol = {
val boxedName = sn.Boxed(name)
@@ -609,8 +625,9 @@ trait Definitions extends reflect.generic.StandardDefinitions {
val module = ScalaPackageClass.newModule(NoPosition, name)
ScalaPackageClass.info.decls.enter(module)
val mclass = module.moduleClass
- mclass.setInfo(ClassInfoType(List(), new Scope, mclass))
+ mclass.setInfo(ClassInfoType(List(AnyRefClass.tpe, AnyValCompanionClass.tpe), new Scope, mclass))
module.setInfo(mclass.tpe)
+ primitiveCompanions += module
val box = newMethod(mclass, nme.box, List(clazz.typeConstructor), boxedClass(clazz).tpe)
boxMethod(clazz) = box
@@ -769,6 +786,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
abbrvTag(UnitClass) = 'V'
initValueClasses()
+ initUnitCompanionObject()
// members of class scala.Any
Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype) setFlag FINAL
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index f50ace8426..2ccab7641a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -389,10 +389,9 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** Is this symbol a type but not a class? */
def isNonClassType = false
- /** Term symbols with the exception of static parts of Java classes and packages
- * and the faux companion objects of primitives. (See tickets #1392 and #3123.)
+ /** Term symbols with the exception of static parts of Java classes and packages.
*/
- final def isValue = isTerm && !(isModule && (hasFlag(PACKAGE | JAVA) || isValueClass(companionClass)))
+ final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA))
final def isVariable = isTerm && hasFlag(MUTABLE) && !isMethod
diff --git a/src/library/scala/runtime/AnyValCompanion.scala b/src/library/scala/runtime/AnyValCompanion.scala
new file mode 100644
index 0000000000..0a6f93805a
--- /dev/null
+++ b/src/library/scala/runtime/AnyValCompanion.scala
@@ -0,0 +1,86 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+package scala.runtime
+
+/** A common supertype for companion classes of primitive types.
+ *
+ * A common trait for /companion/ objects of primitive types comes handy
+ * when parameterizing code on types. For instance, the specialized
+ * annotation is passed a sequence of types on which to specialize:
+ * {{{
+ * class Tuple1[@specialized(Unit, Int, Double) T]
+ * }}}
+ *
+ */
+sealed trait AnyValCompanion
+
+/** A object representing 'object scala.Unit'. It should never be used
+ * directly.
+ */
+object Unit extends AnyValCompanion {
+ override def toString = "object scala.Unit"
+}
+
+/** A object representing 'object scala.Boolean'. It should never be used
+ * directly.
+ */
+object Boolean extends AnyValCompanion {
+ override def toString = "object scala.Boolean"
+}
+
+/** A object representing 'object scala.Byte'. It should never be used
+ * directly.
+ */
+object Byte extends AnyValCompanion {
+ override def toString = "object scala.Byte"
+}
+
+/** A object representing 'object scala.Short'. It should never be used
+ * directly.
+ */
+object Short extends AnyValCompanion {
+ override def toString = "object scala.Short"
+}
+
+/** A object representing 'object scala.Char'. It should never be used
+ * directly.
+ */
+object Char extends AnyValCompanion {
+ override def toString = "object scala.Char"
+}
+
+/** A object representing 'object scala.Int'. It should never be used
+ * directly.
+ */
+object Int extends AnyValCompanion {
+ override def toString = "object scala.Int"
+}
+
+/** A object representing 'object scala.Long'. It should never be used
+ * directly.
+ */
+object Long extends AnyValCompanion {
+ override def toString = "object scala.Long"
+}
+
+/** A object representing 'object scala.Float'. It should never be used
+ * directly.
+ */
+object Float extends AnyValCompanion {
+ override def toString = "object scala.Float"
+}
+
+/** A object representing 'object scala.Double'. It should never be used
+ * directly.
+ */
+object Double extends AnyValCompanion {
+ override def toString = "object scala.Double"
+}
diff --git a/test/files/neg/bug1392.check b/test/files/neg/bug1392.check
deleted file mode 100644
index e4c9630435..0000000000
--- a/test/files/neg/bug1392.check
+++ /dev/null
@@ -1,4 +0,0 @@
-bug1392.scala:1: error: object Int is not a value
-object X extends Application { Int }
- ^
-one error found
diff --git a/test/files/neg/bug1392.scala b/test/files/neg/bug1392.scala
deleted file mode 100644
index 54a4b9e908..0000000000
--- a/test/files/neg/bug1392.scala
+++ /dev/null
@@ -1 +0,0 @@
-object X extends Application { Int }
diff --git a/test/files/neg/bug3123.check b/test/files/neg/bug3123.check
deleted file mode 100644
index 8f5319c9a3..0000000000
--- a/test/files/neg/bug3123.check
+++ /dev/null
@@ -1,4 +0,0 @@
-bug3123.scala:3: error: object Int is not a value
- t match { case Int => true }
- ^
-one error found
diff --git a/test/files/neg/bug3123.scala b/test/files/neg/bug3123.scala
deleted file mode 100644
index 667a1da918..0000000000
--- a/test/files/neg/bug3123.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-object NotAValue {
- def test[T](t : T) {
- t match { case Int => true }
- }
-}