diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2010-04-09 15:42:24 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2010-04-09 15:42:24 +0000 |
commit | d76943f9ae43176980f21f90f400053fe2da3fbf (patch) | |
tree | d43b33f4cc1055f78ec2853164d61171fec17f3c | |
parent | 73648228fffb462113ebfa6222824cc229cf808c (diff) | |
download | scala-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.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 5 | ||||
-rw-r--r-- | src/library/scala/runtime/AnyValCompanion.scala | 86 | ||||
-rw-r--r-- | test/files/neg/bug1392.check | 4 | ||||
-rw-r--r-- | test/files/neg/bug1392.scala | 1 | ||||
-rw-r--r-- | test/files/neg/bug3123.check | 4 | ||||
-rw-r--r-- | test/files/neg/bug3123.scala | 5 |
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 } - } -} |