diff options
59 files changed, 407 insertions, 877 deletions
diff --git a/lib/scala-compiler-src.jar.desired.sha1 b/lib/scala-compiler-src.jar.desired.sha1 index 057d6b26e6..5d32ff0d1d 100644 --- a/lib/scala-compiler-src.jar.desired.sha1 +++ b/lib/scala-compiler-src.jar.desired.sha1 @@ -1 +1 @@ -acfbbb4117b222b488226b4a89d5e732eb59f19c ?scala-compiler-src.jar +2698ecddfcde060a5db2a37e4aa448f4ad5c5891 ?scala-compiler-src.jar diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index d4cad8f868..1a65697c88 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -e0c0f2326622f535aa86978dee74dc7ac86e401b ?scala-compiler.jar +d9ce03a6d3d33234d94577b0cc0093f7a1739d95 ?scala-compiler.jar diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1 index c8515e61de..3175dc3d30 100644 --- a/lib/scala-library-src.jar.desired.sha1 +++ b/lib/scala-library-src.jar.desired.sha1 @@ -1 +1 @@ -52b0ea12b0fe6c2150434fdda3909c2aa927a325 ?scala-library-src.jar +a06b6e42d646e7077325fe1147f1fc9fa22aad7b ?scala-library-src.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 323d3441f8..1543a18c53 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -7a35fcd17b39ea1e13cc8c919e1e556eed81e799 ?scala-library.jar +4b0516ead118899611bbf6b1b21bf7a32e1f1f40 ?scala-library.jar diff --git a/lib/scala-reflect-src.jar.desired.sha1 b/lib/scala-reflect-src.jar.desired.sha1 index 839d77da3a..7dd29fc0bb 100644 --- a/lib/scala-reflect-src.jar.desired.sha1 +++ b/lib/scala-reflect-src.jar.desired.sha1 @@ -1 +1 @@ -fc25fdfd30959e77b85c0c7917005a83890f94a2 ?scala-reflect-src.jar +4f474a08df49c89a04031096093a0eda7875c8b7 ?scala-reflect-src.jar diff --git a/lib/scala-reflect.jar.desired.sha1 b/lib/scala-reflect.jar.desired.sha1 index 88ea78c303..aaea49a8b8 100644 --- a/lib/scala-reflect.jar.desired.sha1 +++ b/lib/scala-reflect.jar.desired.sha1 @@ -1 +1 @@ -5aca838ee9d82be45fb476c1722f71842d5d528e ?scala-reflect.jar +2a2172b2a97a0458ccce846b3a779e7728a7f034 ?scala-reflect.jar diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index bab658e141..2fa9c076dd 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -121,44 +121,26 @@ abstract class GenICode extends SubComponent { m.native = m.symbol.hasAnnotation(definitions.NativeAttr) if (!m.isAbstractMethod && !m.native) { - val staticfield = if (m.symbol.isAccessor && m.symbol.accessed.hasStaticAnnotation) { - val compClass = m.symbol.owner.companionClass - compClass.info.findMember(m.symbol.accessed.name, NoFlags, NoFlags, false) - } else NoSymbol - if (staticfield != NoSymbol) { - // in companion object accessors to @static fields, we access the static field directly - val hostClass = m.symbol.owner.companionClass - if (m.symbol.isGetter) { - ctx1.bb.emit(LOAD_FIELD(staticfield, true) setHostClass hostClass, tree.pos) - ctx1.bb.closeWith(RETURN(m.returnType)) - } else if (m.symbol.isSetter) { - ctx1.bb.emit(LOAD_LOCAL(m.locals.head), tree.pos) - ctx1.bb.emit(STORE_FIELD(staticfield, true), tree.pos) + ctx1 = genLoad(rhs, ctx1, m.returnType); + + // reverse the order of the local variables, to match the source-order + m.locals = m.locals.reverse + + rhs match { + case Block(_, Return(_)) => () + case Return(_) => () + case EmptyTree => + globalError("Concrete method has no definition: " + tree + ( + if (settings.debug.value) "(found: " + m.symbol.owner.info.decls.toList.mkString(", ") + ")" + else "") + ) + case _ => if (ctx1.bb.isEmpty) + ctx1.bb.closeWith(RETURN(m.returnType), rhs.pos) + else ctx1.bb.closeWith(RETURN(m.returnType)) - } else assert(false, "unreachable") - } else { - ctx1 = genLoad(rhs, ctx1, m.returnType); - - // reverse the order of the local variables, to match the source-order - m.locals = m.locals.reverse - - rhs match { - case Block(_, Return(_)) => () - case Return(_) => () - case EmptyTree => - globalError("Concrete method has no definition: " + tree + ( - if (settings.debug.value) "(found: " + m.symbol.owner.info.decls.toList.mkString(", ") + ")" - else "") - ) - case _ => - if (ctx1.bb.isEmpty) - ctx1.bb.closeWith(RETURN(m.returnType), rhs.pos) - else - ctx1.bb.closeWith(RETURN(m.returnType)) - } - if (!ctx1.bb.closed) ctx1.bb.close - prune(ctx1.method) } + if (!ctx1.bb.closed) ctx1.bb.close + prune(ctx1.method) } else ctx1.method.setCode(NoCode) ctx1 @@ -900,47 +882,6 @@ abstract class GenICode extends SubComponent { generatedType = toTypeKind(fun.symbol.tpe.resultType) ctx1 - case app @ Apply(fun @ Select(qual, _), args) - if !ctx.method.symbol.isStaticConstructor - && fun.symbol.isAccessor && fun.symbol.accessed.hasStaticAnnotation - && qual.tpe.typeSymbol.orElse(fun.symbol.owner).companionClass != NoSymbol => - // bypass the accessor to the companion object and load the static field directly - // this bypass is not done: - // - if the static intializer for the static field itself - // - if there is no companion class of the object owner - this happens in the REPL - def genLoadApply5 = { - val sym = fun.symbol - generatedType = toTypeKind(sym.accessed.info) - val hostOwner = qual.tpe.typeSymbol.orElse(sym.owner) - val hostClass = hostOwner.companionClass - val staticfield = hostClass.info.findMember(sym.accessed.name, NoFlags, NoFlags, false) orElse { - if (!currentRun.compiles(hostOwner)) { - // hostOwner was separately compiled -- the static field symbol needs to be recreated in hostClass - import Flags._ - debuglog("recreating sym.accessed.name: " + sym.accessed.name) - val objectfield = hostOwner.info.findMember(sym.accessed.name, NoFlags, NoFlags, false) - val staticfield = hostClass.newVariable(newTermName(sym.accessed.name.toString), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo objectfield.tpe - staticfield.addAnnotation(definitions.StaticClass) - hostClass.info.decls enter staticfield - staticfield - } else NoSymbol - } - - if (sym.isGetter) { - ctx.bb.emit(LOAD_FIELD(staticfield, true) setHostClass hostClass, tree.pos) - ctx - } else if (sym.isSetter) { - val ctx1 = genLoadArguments(args, sym.info.paramTypes, ctx) - ctx1.bb.emit(STORE_FIELD(staticfield, true), tree.pos) - ctx1.bb.emit(CONSTANT(Constant(false)), tree.pos) - ctx1 - } else { - assert(false, "supposedly unreachable") - ctx - } - } - genLoadApply5 - case app @ Apply(fun, args) => def genLoadApply6 = { val sym = fun.symbol @@ -1732,12 +1673,8 @@ abstract class GenICode extends SubComponent { * backend emits them as static). * No code is needed for this module symbol. */ - for ( - f <- cls.info.decls; - if !f.isMethod && f.isTerm && !f.isModule && !(f.owner.isModuleClass && f.hasStaticAnnotation) - ) { + for (f <- cls.info.decls ; if !f.isMethod && f.isTerm && !f.isModule) ctx.clazz addField new IField(f) - } } /** diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 1653ca9c2a..28966eef08 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -1190,9 +1190,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { log(s"No forwarder for non-public member $m") else { log("Adding static forwarder for '%s' from %s to '%s'".format(m, jclassName, moduleClass)) - if (m.isAccessor && m.accessed.hasStaticAnnotation) { - log("@static: accessor " + m + ", accessed: " + m.accessed) - } else addForwarder(isRemoteClass, jclass, moduleClass, m) + addForwarder(isRemoteClass, jclass, moduleClass, m) } } } @@ -1697,7 +1695,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters { jmethod = clinitMethod jMethodName = CLASS_CONSTRUCTOR_NAME jmethod.visitCode() - computeLocalVarsIndex(m) genCode(m, false, true) jmethod.visitMaxs(0, 0) // just to follow protocol, dummy arguments jmethod.visitEnd() diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index a2151633a7..62c281b82f 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1023,8 +1023,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with method = m jmethod = clinitMethod - - computeLocalVarsIndex(m) genCode(m) case None => legacyStaticInitializer(cls, clinit) @@ -1126,9 +1124,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with log("No forwarder for " + m + " due to conflict with " + linkedClass.info.member(m.name)) else { log("Adding static forwarder for '%s' from %s to '%s'".format(m, className, moduleClass)) - if (m.isAccessor && m.accessed.hasStaticAnnotation) { - log("@static: accessor " + m + ", accessed: " + m.accessed) - } else addForwarder(jclass, moduleClass, m) + addForwarder(jclass, moduleClass, m) } } } diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index dff9a65649..fa7a53f888 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -23,12 +23,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL { new CleanUpTransformer(unit) class CleanUpTransformer(unit: CompilationUnit) extends Transformer { - private val newStaticMembers = mutable.Buffer.empty[Tree] - private val newStaticInits = mutable.Buffer.empty[Tree] - private val symbolsStoredAsStatic = mutable.Map.empty[String, Symbol] - private val staticBodies = mutable.Map.empty[(Symbol, Symbol), Tree] - private val syntheticClasses = mutable.Map.empty[Symbol, mutable.Set[Tree]] // package and trees - private val classNames = mutable.Map.empty[Symbol, Set[Name]] + private val newStaticMembers = mutable.Buffer.empty[Tree] + private val newStaticInits = mutable.Buffer.empty[Tree] + private val symbolsStoredAsStatic = mutable.Map.empty[String, Symbol] private def clearStatics() { newStaticMembers.clear() newStaticInits.clear() @@ -48,9 +45,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL { result } private def transformTemplate(tree: Tree) = { - val t @ Template(parents, self, body) = tree + val Template(parents, self, body) = tree clearStatics() - val newBody = transformTrees(body) val templ = deriveTemplate(tree)(_ => transformTrees(newStaticMembers.toList) ::: newBody) try addStaticInits(templ) // postprocess to include static ctors @@ -550,80 +546,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL { else tree } - case DefDef(mods, name, tps, vps, tp, rhs) if tree.symbol.hasStaticAnnotation => - reporter.error(tree.pos, "The @static annotation is not allowed on method definitions.") - super.transform(tree) - - case ValDef(mods, name, tpt, rhs) if tree.symbol.hasStaticAnnotation => - def transformStaticValDef = { - log("moving @static valdef field: " + name + ", in: " + tree.symbol.owner) - val sym = tree.symbol - val owner = sym.owner - - val staticBeforeLifting = atPhase(currentRun.erasurePhase) { owner.isStatic } - val isPrivate = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PRIVATE) } - val isProtected = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PROTECTED) } - val isLazy = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(LAZY) } - if (!owner.isModuleClass || !staticBeforeLifting) { - if (!sym.isSynthetic) { - reporter.error(tree.pos, "Only members of top-level objects and their nested objects can be annotated with @static.") - tree.symbol.removeAnnotation(StaticClass) - } - super.transform(tree) - } else if (isPrivate || isProtected) { - reporter.error(tree.pos, "The @static annotation is only allowed on public members.") - tree.symbol.removeAnnotation(StaticClass) - super.transform(tree) - } else if (isLazy) { - reporter.error(tree.pos, "The @static annotation is not allowed on lazy members.") - tree.symbol.removeAnnotation(StaticClass) - super.transform(tree) - } else if (owner.isModuleClass) { - val linkedClass = owner.companionClass match { - case NoSymbol => - // create the companion class if it does not exist - val enclosing = owner.owner - val compclass = enclosing.newClass(newTypeName(owner.name.toString)) - compclass setInfo ClassInfoType(List(ObjectClass.tpe), newScope, compclass) - enclosing.info.decls enter compclass - - val compclstree = ClassDef(compclass, NoMods, ListOfNil, ListOfNil, List(), tree.pos) - - syntheticClasses.getOrElseUpdate(enclosing, mutable.Set()) += compclstree - - compclass - case comp => comp - } - - // create a static field in the companion class for this @static field - val stfieldSym = linkedClass.newValue(newTermName(name), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo sym.tpe - if (sym.isMutable) stfieldSym.setFlag(MUTABLE) - stfieldSym.addAnnotation(StaticClass) - - val names = classNames.getOrElseUpdate(linkedClass, linkedClass.info.decls.collect { - case sym if sym.name.isTermName => sym.name - } toSet) - if (names(stfieldSym.name)) { - reporter.error( - tree.pos, - "@static annotated field " + tree.symbol.name + " has the same name as a member of class " + linkedClass.name - ) - } else { - linkedClass.info.decls enter stfieldSym - - val initializerBody = rhs - - // static field was previously initialized in the companion object itself, like this: - // staticBodies((linkedClass, stfieldSym)) = Select(This(owner), sym.getter(owner)) - // instead, we move the initializer to the static ctor of the companion class - // we save the entire ValDef/DefDef to extract the rhs later - staticBodies((linkedClass, stfieldSym)) = tree - } - } - super.transform(tree) - } - transformStaticValDef - /* MSIL requires that the stack is empty at the end of a try-block. * Hence, we here rewrite all try blocks with a result != {Unit, All} such that they * store their result in a local variable. The catch blocks are adjusted as well. @@ -738,11 +660,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL { if (newStaticInits.isEmpty) template else { - val ctorBody = newStaticInits.toList flatMap { - case Block(stats, expr) => stats :+ expr - case t => List(t) - } - val newCtor = findStaticCtor(template) match { // in case there already were static ctors - augment existing ones // currently, however, static ctors aren't being generated anywhere else @@ -751,15 +668,15 @@ abstract class CleanUp extends Transform with ast.TreeDSL { deriveDefDef(ctor) { case block @ Block(stats, expr) => // need to add inits to existing block - treeCopy.Block(block, ctorBody ::: stats, expr) + treeCopy.Block(block, newStaticInits.toList ::: stats, expr) case term: TermTree => // need to create a new block with inits and the old term - treeCopy.Block(term, ctorBody, term) + treeCopy.Block(term, newStaticInits.toList, term) } case _ => // create new static ctor val staticCtorSym = currentClass.newStaticConstructor(template.pos) - val rhs = Block(ctorBody, Literal(Constant(()))) + val rhs = Block(newStaticInits.toList, Literal(Constant(()))) localTyper.typedPos(template.pos)(DefDef(staticCtorSym, rhs)) } @@ -767,62 +684,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL { } } - private def addStaticDeclarations(tree: Template, clazz: Symbol) { - // add static field initializer statements for each static field in clazz - if (!clazz.isModuleClass) for { - staticSym <- clazz.info.decls - if staticSym.hasStaticAnnotation - } staticSym match { - case stfieldSym if (stfieldSym.isValue && !stfieldSym.isMethod) || stfieldSym.isVariable => - log(stfieldSym + " is value: " + stfieldSym.isValue) - val valdef = staticBodies((clazz, stfieldSym)) - val ValDef(_, _, _, rhs) = valdef - val fixedrhs = rhs.changeOwner((valdef.symbol, clazz.info.decl(nme.CONSTRUCTOR))) - - val stfieldDef = localTyper.typedPos(tree.pos)(VAL(stfieldSym) === EmptyTree) - val flattenedInit = fixedrhs match { - case Block(stats, expr) => Block(stats, REF(stfieldSym) === expr) - case rhs => REF(stfieldSym) === rhs - } - val stfieldInit = localTyper.typedPos(tree.pos)(flattenedInit) - - // add field definition to new defs - newStaticMembers append stfieldDef - newStaticInits append stfieldInit - case _ => // ignore @static on other members - } - } - - - - override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = { - super.transformStats(stats, exprOwner) ++ { - // flush pending synthetic classes created in this owner - val synthclassdefs = syntheticClasses.get(exprOwner).toList.flatten - syntheticClasses -= exprOwner - synthclassdefs map { - cdef => localTyper.typedPos(cdef.pos)(cdef) - } - } map { - case clsdef @ ClassDef(mods, name, tparams, t @ Template(parent, self, body)) => - // process all classes in the package again to add static initializers - clearStatics() - - addStaticDeclarations(t, clsdef.symbol) - - val templ = deriveTemplate(t)(_ => transformTrees(newStaticMembers.toList) ::: body) - val ntempl = - try addStaticInits(templ) - finally clearStatics() - - val derived = deriveClassDef(clsdef)(_ => ntempl) - classNames.remove(clsdef.symbol) - derived - - case stat => stat - } - } - } // CleanUpTransformer } diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index afc109c47a..23b15a9033 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -186,15 +186,12 @@ abstract class Constructors extends Transform with ast.TreeDSL { // before the superclass constructor call, otherwise it goes after. // Lazy vals don't get the assignment in the constructor. if (!stat.symbol.tpe.isInstanceOf[ConstantType]) { - if (stat.symbol.hasStaticAnnotation) { - debuglog("@static annotated field initialization skipped.") - defBuf += deriveValDef(stat)(tree => tree) - } else if (rhs != EmptyTree && !stat.symbol.isLazy) { + if (rhs != EmptyTree && !stat.symbol.isLazy) { val rhs1 = intoConstructor(stat.symbol, rhs); (if (canBeMoved(stat)) constrPrefixBuf else constrStatBuf) += mkAssign( stat.symbol, rhs1) - defBuf += deriveValDef(stat)(_ => EmptyTree) } + defBuf += deriveValDef(stat)(_ => EmptyTree) } case ClassDef(_, _, _, _) => // classes are treated recursively, and left in the template diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index b6d54f114e..c41ff20229 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -154,7 +154,7 @@ abstract class LambdaLift extends InfoTransform { private def markCalled(sym: Symbol, owner: Symbol) { debuglog("mark called: " + sym + " of " + sym.owner + " is called by " + owner) symSet(called, owner) addEntry sym - if (sym.enclClass != owner.enclClass) calledFromInner addEntry sym + if (sym.enclClass != owner.enclClass) calledFromInner += sym } /** The traverse function */ diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index d941519958..091224c88a 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -175,7 +175,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order verify(expr) - def wrap(expr0: Tree): Tree = { + def wrap(expr0: Tree): ModuleDef = { val (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = true) val (obj, mclazz) = rootMirror.EmptyPackageClass.newModuleAndClassSymbol( @@ -213,11 +213,11 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => var cleanedUp = resetLocalAttrs(moduledef) trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value)) - cleanedUp + cleanedUp.asInstanceOf[ModuleDef] } val mdef = wrap(expr) - val pdef = PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(mdef)) + val pdef = PackageDef(Ident(mdef.name), List(mdef)) val unit = new CompilationUnit(NoSourceFile) unit.body = pdef diff --git a/src/library/scala/App.scala b/src/library/scala/App.scala index 85d2f9075e..a1e5e74e2f 100644 --- a/src/library/scala/App.scala +++ b/src/library/scala/App.scala @@ -22,6 +22,16 @@ import scala.collection.mutable.ListBuffer * * `args` returns the current command line arguments as an array. * + * ==Caveats== + * + * '''''It should be noted that this trait is implemented using the [[DelayedInit]] + * functionality, which means that fields of the object will not have been initialized + * before the main method has been executed.''''' + * + * It should also be noted that the `main` method will not normally need to be overridden: + * the purpose is to turn the whole class body into the “main method”. You should only + * chose to override it if you know what you are doing. + * * @author Martin Odersky * @version 2.1, 15/02/2011 */ diff --git a/src/library/scala/annotation/static.scala b/src/library/scala/annotation/static.scala deleted file mode 100644 index f2955c756c..0000000000 --- a/src/library/scala/annotation/static.scala +++ /dev/null @@ -1,20 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.annotation - -/** - * An annotation that marks a member in the companion object as static - * and ensures that the compiler generates static fields/methods for it. - * This is important for Java interoperability and performance reasons. - * - * @since 2.10 - */ -final class static extends StaticAnnotation { - // TODO document exact semantics above! -} diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala index 12066055e9..74f576b0f7 100644 --- a/src/library/scala/collection/mutable/FlatHashTable.scala +++ b/src/library/scala/collection/mutable/FlatHashTable.scala @@ -44,7 +44,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { */ @transient protected var sizemap: Array[Int] = null - @transient var seedvalue: Int = tableSizeSeed + @transient protected var seedvalue: Int = tableSizeSeed import HashTable.powerOfTwo @@ -109,7 +109,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { } /** Finds an entry in the hash table if such an element exists. */ - def findEntry(elem: A): Option[A] = { + protected def findEntry(elem: A): Option[A] = { var h = index(elemHashCode(elem)) var entry = table(h) while (null != entry && entry != elem) { @@ -120,7 +120,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { } /** Checks whether an element is contained in the hash table. */ - def containsEntry(elem: A): Boolean = { + protected def containsEntry(elem: A): Boolean = { var h = index(elemHashCode(elem)) var entry = table(h) while (null != entry && entry != elem) { @@ -133,7 +133,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { /** Add entry if not yet in table. * @return Returns `true` if a new entry was added, `false` otherwise. */ - def addEntry(elem: A) : Boolean = { + protected def addEntry(elem: A) : Boolean = { var h = index(elemHashCode(elem)) var entry = table(h) while (null != entry) { @@ -150,7 +150,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { } /** Removes an entry from the hash table, returning an option value with the element, or `None` if it didn't exist. */ - def removeEntry(elem: A) : Option[A] = { + protected def removeEntry(elem: A) : Option[A] = { if (tableDebug) checkConsistent() def precedes(i: Int, j: Int) = { val d = table.length >> 1 @@ -185,7 +185,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { None } - def iterator: Iterator[A] = new AbstractIterator[A] { + protected def iterator: Iterator[A] = new AbstractIterator[A] { private var i = 0 def hasNext: Boolean = { while (i < table.length && (null == table(i))) i += 1 diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala index da486f4042..be85df3c28 100644 --- a/src/library/scala/collection/mutable/HashMap.scala +++ b/src/library/scala/collection/mutable/HashMap.scala @@ -49,7 +49,7 @@ extends AbstractMap[A, B] type Entry = DefaultEntry[A, B] override def empty: HashMap[A, B] = HashMap.empty[A, B] - override def clear() = clearTable() + override def clear() { clearTable() } override def size: Int = tableSize def this() = this(null) @@ -57,22 +57,23 @@ extends AbstractMap[A, B] override def par = new ParHashMap[A, B](hashTableContents) // contains and apply overridden to avoid option allocations. - override def contains(key: A) = findEntry(key) != null + override def contains(key: A): Boolean = findEntry(key) != null + override def apply(key: A): B = { val result = findEntry(key) - if (result == null) default(key) + if (result eq null) default(key) else result.value } def get(key: A): Option[B] = { val e = findEntry(key) - if (e == null) None + if (e eq null) None else Some(e.value) } override def put(key: A, value: B): Option[B] = { - val e = findEntry(key) - if (e == null) { addEntry(new Entry(key, value)); None } + val e = findOrAddEntry(key, value) + if (e eq null) None else { val v = e.value; e.value = value; Some(v) } } @@ -85,9 +86,8 @@ extends AbstractMap[A, B] } def += (kv: (A, B)): this.type = { - val e = findEntry(kv._1) - if (e == null) addEntry(new Entry(kv._1, kv._2)) - else e.value = kv._2 + val e = findOrAddEntry(kv._1, kv._2) + if (e ne null) e.value = kv._2 this } @@ -127,12 +127,19 @@ extends AbstractMap[A, B] if (!isSizeMapDefined) sizeMapInitAndRebuild } else sizeMapDisable + protected def createNewEntry[B1](key: A, value: B1): Entry = { + new Entry(key, value.asInstanceOf[B]) + } + private def writeObject(out: java.io.ObjectOutputStream) { - serializeTo(out, _.value) + serializeTo(out, { entry => + out.writeObject(entry.key) + out.writeObject(entry.value) + }) } private def readObject(in: java.io.ObjectInputStream) { - init[B](in, new Entry(_, _)) + init(in, createNewEntry(in.readObject().asInstanceOf[A], in.readObject())) } } diff --git a/src/library/scala/collection/mutable/HashSet.scala b/src/library/scala/collection/mutable/HashSet.scala index b263b46d36..a5b636c83d 100644 --- a/src/library/scala/collection/mutable/HashSet.scala +++ b/src/library/scala/collection/mutable/HashSet.scala @@ -53,7 +53,7 @@ extends AbstractSet[A] override def companion: GenericCompanion[HashSet] = HashSet - override def size = tableSize + override def size: Int = tableSize def contains(elem: A): Boolean = containsEntry(elem) @@ -67,7 +67,9 @@ extends AbstractSet[A] override def remove(elem: A): Boolean = removeEntry(elem).isDefined - override def clear() = clearTable() + override def clear() { clearTable() } + + override def iterator: Iterator[A] = super[FlatHashTable].iterator override def foreach[U](f: A => U) { var i = 0 diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index 968d99d042..eb6717393b 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -32,6 +32,9 @@ package mutable * @tparam A type of the elements contained in this hash table. */ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashUtils[A] { + // Replacing Entry type parameter by abstract type member here allows to not expose to public + // implementation-specific entry classes such as `DefaultEntry` or `LinkedEntry`. + // However, I'm afraid it's too late now for such breaking change. import HashTable._ @transient protected var _loadFactor = defaultLoadFactor @@ -52,7 +55,7 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU */ @transient protected var sizemap: Array[Int] = null - @transient var seedvalue: Int = tableSizeSeed + @transient protected var seedvalue: Int = tableSizeSeed protected def tableSizeSeed = Integer.bitCount(table.length - 1) @@ -75,11 +78,10 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU } /** - * Initializes the collection from the input stream. `f` will be called for each key/value pair - * read from the input stream in the order determined by the stream. This is useful for - * structures where iteration order is important (e.g. LinkedHashMap). + * Initializes the collection from the input stream. `readEntry` will be called for each + * entry to be read from the input stream. */ - private[collection] def init[B](in: java.io.ObjectInputStream, f: (A, B) => Entry) { + private[collection] def init(in: java.io.ObjectInputStream, readEntry: => Entry) { in.defaultReadObject _loadFactor = in.readInt() @@ -100,35 +102,34 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU var index = 0 while (index < size) { - addEntry(f(in.readObject().asInstanceOf[A], in.readObject().asInstanceOf[B])) + addEntry(readEntry) index += 1 } } /** * Serializes the collection to the output stream by saving the load factor, collection - * size, collection keys and collection values. `value` is responsible for providing a value - * from an entry. + * size and collection entries. `writeEntry` is responsible for writing an entry to the stream. * - * `foreach` determines the order in which the key/value pairs are saved to the stream. To + * `foreachEntry` determines the order in which the key/value pairs are saved to the stream. To * deserialize, `init` should be used. */ - private[collection] def serializeTo[B](out: java.io.ObjectOutputStream, value: Entry => B) { + private[collection] def serializeTo(out: java.io.ObjectOutputStream, writeEntry: Entry => Unit) { out.defaultWriteObject out.writeInt(_loadFactor) out.writeInt(tableSize) out.writeInt(seedvalue) out.writeBoolean(isSizeMapDefined) - foreachEntry { entry => - out.writeObject(entry.key) - out.writeObject(value(entry)) - } + + foreachEntry(writeEntry) } /** Find entry with given key in table, null if not found. */ - protected def findEntry(key: A): Entry = { - val h = index(elemHashCode(key)) + protected def findEntry(key: A): Entry = + findEntry0(key, index(elemHashCode(key))) + + private[this] def findEntry0(key: A, h: Int): Entry = { var e = table(h).asInstanceOf[Entry] while (e != null && !elemEquals(e.key, key)) e = e.next e @@ -138,7 +139,10 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU * pre: no entry with same key exists */ protected def addEntry(e: Entry) { - val h = index(elemHashCode(e.key)) + addEntry0(e, index(elemHashCode(e.key))) + } + + private[this] def addEntry0(e: Entry, h: Int) { e.next = table(h).asInstanceOf[Entry] table(h) = e tableSize = tableSize + 1 @@ -147,6 +151,24 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU resize(2 * table.length) } + /** Find entry with given key in table, or add new one if not found. + * May be somewhat faster then `findEntry`/`addEntry` pair as it + * computes entry's hash index only once. + * Returns entry found in table or null. + * New entries are created by calling `createNewEntry` method. + */ + protected def findOrAddEntry[B](key: A, value: B): Entry = { + val h = index(elemHashCode(key)) + val e = findEntry0(key, h) + if (e ne null) e else { addEntry0(createNewEntry(key, value), h); null } + } + + /** Creates new entry to be immediately inserted into the hashtable. + * This method is guaranteed to be called only once and in case that the entry + * will be added. In other words, an implementation may be side-effecting. + */ + protected def createNewEntry[B](key: A, value: B): Entry + /** Remove entry from table if present. */ protected def removeEntry(key: A) : Entry = { @@ -195,7 +217,7 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU } /** Avoid iterator for a 2x faster traversal. */ - protected def foreachEntry[C](f: Entry => C) { + protected def foreachEntry[U](f: Entry => U) { val iterTable = table var idx = lastPopulatedIndex var es = iterTable(idx) diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala index 5643e070f8..5028884a8e 100644 --- a/src/library/scala/collection/mutable/LinkedHashMap.scala +++ b/src/library/scala/collection/mutable/LinkedHashMap.scala @@ -67,23 +67,9 @@ class LinkedHashMap[A, B] extends AbstractMap[A, B] } override def put(key: A, value: B): Option[B] = { - val e = findEntry(key) - if (e == null) { - val e = new Entry(key, value) - addEntry(e) - updateLinkedEntries(e) - None - } else { - val v = e.value - e.value = value - Some(v) - } - } - - private def updateLinkedEntries(e: Entry) { - if (firstEntry == null) firstEntry = e - else { lastEntry.later = e; e.earlier = lastEntry } - lastEntry = e + val e = findOrAddEntry(key, value) + if (e eq null) None + else { val v = e.value; e.value = value; Some(v) } } override def remove(key: A): Option[B] = { @@ -143,7 +129,7 @@ class LinkedHashMap[A, B] extends AbstractMap[A, B] else Iterator.empty.next } - override def foreach[U](f: ((A, B)) => U) = { + override def foreach[U](f: ((A, B)) => U) { var cur = firstEntry while (cur ne null) { f((cur.key, cur.value)) @@ -151,7 +137,7 @@ class LinkedHashMap[A, B] extends AbstractMap[A, B] } } - protected override def foreachEntry[C](f: Entry => C) { + protected override def foreachEntry[U](f: Entry => U) { var cur = firstEntry while (cur ne null) { f(cur) @@ -159,22 +145,29 @@ class LinkedHashMap[A, B] extends AbstractMap[A, B] } } + protected def createNewEntry[B1](key: A, value: B1): Entry = { + val e = new Entry(key, value.asInstanceOf[B]) + if (firstEntry eq null) firstEntry = e + else { lastEntry.later = e; e.earlier = lastEntry } + lastEntry = e + e + } + override def clear() { clearTable() firstEntry = null } private def writeObject(out: java.io.ObjectOutputStream) { - serializeTo(out, _.value) + serializeTo(out, { entry => + out.writeObject(entry.key) + out.writeObject(entry.value) + }) } private def readObject(in: java.io.ObjectInputStream) { firstEntry = null lastEntry = null - init[B](in, { (key, value) => - val entry = new Entry(key, value) - updateLinkedEntries(entry) - entry - }) + init(in, createNewEntry(in.readObject().asInstanceOf[A], in.readObject())) } } diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index 3f789f9fa2..88bad5ff9b 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -19,6 +19,7 @@ import generic._ * * @author Matthias Zenger * @author Martin Odersky + * @author Pavel Pavlov * @version 2.0, 31/12/2006 * @since 1 * @@ -43,46 +44,82 @@ class LinkedHashSet[A] extends AbstractSet[A] with Set[A] with GenericSetTemplate[A, LinkedHashSet] with SetLike[A, LinkedHashSet[A]] - with FlatHashTable[A] + with HashTable[A, LinkedHashSet.Entry[A]] with Serializable { override def companion: GenericCompanion[LinkedHashSet] = LinkedHashSet - @transient private[this] var ordered = new ListBuffer[A] + type Entry = LinkedHashSet.Entry[A] - override def size = tableSize + @transient protected var firstEntry: Entry = null + @transient protected var lastEntry: Entry = null - def contains(elem: A): Boolean = containsEntry(elem) + override def size: Int = tableSize + + def contains(elem: A): Boolean = findEntry(elem) ne null def += (elem: A): this.type = { add(elem); this } def -= (elem: A): this.type = { remove(elem); this } - override def add(elem: A): Boolean = - if (addEntry(elem)) { ordered += elem; true } - else false + override def add(elem: A): Boolean = findOrAddEntry(elem, null) eq null + + override def remove(elem: A): Boolean = { + val e = removeEntry(elem) + if (e eq null) false + else { + if (e.earlier eq null) firstEntry = e.later + else e.earlier.later = e.later + if (e.later eq null) lastEntry = e.earlier + else e.later.earlier = e.earlier + true + } + } - override def remove(elem: A): Boolean = - removeEntry(elem) match { - case None => false - case _ => ordered -= elem; true + def iterator: Iterator[A] = new AbstractIterator[A] { + private var cur = firstEntry + def hasNext = cur ne null + def next = + if (hasNext) { val res = cur.key; cur = cur.later; res } + else Iterator.empty.next + } + + override def foreach[U](f: A => U) { + var cur = firstEntry + while (cur ne null) { + f(cur.key) + cur = cur.later } + } - override def clear() { - ordered.clear() - clearTable() + protected override def foreachEntry[U](f: Entry => U) { + var cur = firstEntry + while (cur ne null) { + f(cur) + cur = cur.later + } } - override def iterator: Iterator[A] = ordered.iterator + protected def createNewEntry[B](key: A, dummy: B): Entry = { + val e = new Entry(key) + if (firstEntry eq null) firstEntry = e + else { lastEntry.later = e; e.earlier = lastEntry } + lastEntry = e + e + } - override def foreach[U](f: A => U) = ordered foreach f + override def clear() { + clearTable() + firstEntry = null + } - private def writeObject(s: java.io.ObjectOutputStream) { - serializeTo(s) + private def writeObject(out: java.io.ObjectOutputStream) { + serializeTo(out, { e => out.writeObject(e.key) }) } private def readObject(in: java.io.ObjectInputStream) { - ordered = new ListBuffer[A] - init(in, ordered += _) + firstEntry = null + lastEntry = null + init(in, createNewEntry(in.readObject().asInstanceOf[A], null)) } } @@ -93,5 +130,13 @@ class LinkedHashSet[A] extends AbstractSet[A] object LinkedHashSet extends MutableSetFactory[LinkedHashSet] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, LinkedHashSet[A]] = setCanBuildFrom[A] override def empty[A]: LinkedHashSet[A] = new LinkedHashSet[A] + + /** Class for the linked hash set entry, used internally. + * @since 2.10 + */ + private[scala] final class Entry[A](val key: A) extends HashEntry[A, Entry[A]] with Serializable { + var earlier: Entry[A] = null + var later: Entry[A] = null + } } diff --git a/src/library/scala/collection/parallel/mutable/ParHashMap.scala b/src/library/scala/collection/parallel/mutable/ParHashMap.scala index 1921727ce3..fad7ddad59 100644 --- a/src/library/scala/collection/parallel/mutable/ParHashMap.scala +++ b/src/library/scala/collection/parallel/mutable/ParHashMap.scala @@ -67,13 +67,13 @@ self => def get(key: K): Option[V] = { val e = findEntry(key) - if (e == null) None + if (e eq null) None else Some(e.value) } def put(key: K, value: V): Option[V] = { - val e = findEntry(key) - if (e == null) { addEntry(new Entry(key, value)); None } + val e = findOrAddEntry(key, value) + if (e eq null) None else { val v = e.value; e.value = value; Some(v) } } @@ -86,9 +86,8 @@ self => } def += (kv: (K, V)): this.type = { - val e = findEntry(kv._1) - if (e == null) addEntry(new Entry(kv._1, kv._2)) - else e.value = kv._2 + val e = findOrAddEntry(kv._1, kv._2) + if (e ne null) e.value = kv._2 this } @@ -103,12 +102,19 @@ self => new ParHashMapIterator(idxFrom, idxUntil, totalSz, es) } + protected def createNewEntry[V1](key: K, value: V1): Entry = { + new Entry(key, value.asInstanceOf[V]) + } + private def writeObject(out: java.io.ObjectOutputStream) { - serializeTo(out, _.value) + serializeTo(out, { entry => + out.writeObject(entry.key) + out.writeObject(entry.value) + }) } private def readObject(in: java.io.ObjectInputStream) { - init[V](in, new Entry(_, _)) + init(in, createNewEntry(in.readObject().asInstanceOf[K], in.readObject())) } private[parallel] override def brokenInvariants = { @@ -190,7 +196,9 @@ extends scala.collection.parallel.BucketCombiner[(K, V), ParHashMap[K, V], Defau // construct a normal table and fill it sequentially // TODO parallelize by keeping separate sizemaps and merging them object table extends HashTable[K, DefaultEntry[K, V]] { - def insertEntry(e: DefaultEntry[K, V]) = if (super.findEntry(e.key) eq null) super.addEntry(e) + type Entry = DefaultEntry[K, V] + def insertEntry(e: Entry) { super.findOrAddEntry(e.key, e) } + def createNewEntry[E](key: K, entry: E): Entry = entry.asInstanceOf[Entry] sizeMapInit(table.length) } var i = 0 @@ -251,6 +259,7 @@ extends scala.collection.parallel.BucketCombiner[(K, V), ParHashMap[K, V], Defau assert(h >= block * blocksize && h < (block + 1) * blocksize) } } + protected def createNewEntry[X](key: K, x: X) = ??? } /* tasks */ diff --git a/src/library/scala/collection/parallel/mutable/ParHashSet.scala b/src/library/scala/collection/parallel/mutable/ParHashSet.scala index 7b5b8e3ceb..aef9f6856b 100644 --- a/src/library/scala/collection/parallel/mutable/ParHashSet.scala +++ b/src/library/scala/collection/parallel/mutable/ParHashSet.scala @@ -158,12 +158,12 @@ with scala.collection.mutable.FlatHashTable.HashUtils[T] { val tbl = new FlatHashTable[T] { sizeMapInit(table.length) seedvalue = ParHashSetCombiner.this.seedvalue + for { + buffer <- buckets; + if buffer ne null; + elem <- buffer + } addEntry(elem.asInstanceOf[T]) } - for { - buffer <- buckets; - if buffer ne null; - elem <- buffer - } tbl.addEntry(elem.asInstanceOf[T]) tbl.hashTableContents } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 4a5ace4248..48a658192b 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -932,7 +932,6 @@ trait Definitions extends api.StandardDefinitions { lazy val SwitchClass = requiredClass[scala.annotation.switch] lazy val TailrecClass = requiredClass[scala.annotation.tailrec] lazy val VarargsClass = requiredClass[scala.annotation.varargs] - lazy val StaticClass = requiredClass[scala.annotation.static] lazy val uncheckedStableClass = requiredClass[scala.annotation.unchecked.uncheckedStable] lazy val uncheckedVarianceClass = requiredClass[scala.annotation.unchecked.uncheckedVariance] diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 22f5b391b8..2f305296f5 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -246,7 +246,6 @@ trait StdNames { final val BeanPropertyAnnot: NameType = "BeanProperty" final val BooleanBeanPropertyAnnot: NameType = "BooleanBeanProperty" final val bridgeAnnot: NameType = "bridge" - final val staticAnnot: NameType = "static" // Classfile Attributes final val AnnotationDefaultATTR: NameType = "AnnotationDefault" diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index b04cf4ff9f..74f4769fec 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -697,7 +697,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => || hasAnnotation(SerializableAttr) // last part can be removed, @serializable annotation is deprecated ) def hasBridgeAnnotation = hasAnnotation(BridgeClass) - def hasStaticAnnotation = hasAnnotation(StaticClass) def isDeprecated = hasAnnotation(DeprecatedAttr) def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0) def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1) diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 47978821a3..0d9e90d3a6 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -148,8 +148,10 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUnive object AnnotationClass { def unapply(x: jClass[_]) = x.isAnnotation } object ConstantArg { - def enumToSymbol(enum: Enum[_]): Symbol = - classToScala(enum.getClass).typeSignature.declaration(enum.name: TermName) + def enumToSymbol(enum: Enum[_]): Symbol = { + val staticPartOfEnum = classToScala(enum.getClass).companionSymbol + staticPartOfEnum.typeSignature.declaration(enum.name: TermName) + } def unapply(schemaAndValue: (jClass[_], Any)): Option[Any] = schemaAndValue match { case (StringClass | PrimitiveClass(), value) => Some(value) @@ -659,7 +661,6 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUnive } override def complete(sym: Symbol): Unit = { - if (jclazz.isEnum) throw new ScalaReflectionException("implementation restriction: Java enums are not supported") load(sym) completeRest() } @@ -1024,13 +1025,12 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUnive rawToExistential(typeRef(clazz.owner.thisType, clazz, List())) } case japplied: ParameterizedType => - val (pre, sym) = typeToScala(japplied.getRawType) match { - case ExistentialType(tparams, TypeRef(pre, sym, _)) => (pre, sym) - case TypeRef(pre, sym, _) => (pre, sym) - } + // http://stackoverflow.com/questions/5767122/parameterizedtype-getrawtype-returns-j-l-r-type-not-class + val sym = classToScala(japplied.getRawType.asInstanceOf[jClass[_]]) + val pre = sym.owner.thisType val args0 = japplied.getActualTypeArguments val (args, bounds) = targsToScala(pre.typeSymbol, args0.toList) - ExistentialType(bounds, typeRef(pre, sym, args)) + newExistentialType(bounds, typeRef(pre, sym, args)) case jarr: GenericArrayType => arrayType(typeToScala(jarr.getGenericComponentType)) case jtvar: jTypeVariable[_] => diff --git a/test/files/jvm/serialization-new.check b/test/files/jvm/serialization-new.check index fa51c6a879..f886cfe29c 100644 --- a/test/files/jvm/serialization-new.check +++ b/test/files/jvm/serialization-new.check @@ -168,6 +168,30 @@ x = History() y = History() x equals y: true, y equals x: true +x = Map(Linked -> 1, Hash -> 2, Map -> 3) +y = Map(Linked -> 1, Hash -> 2, Map -> 3) +x equals y: true, y equals x: true + +x = ArrayBuffer((Linked,1), (Hash,2), (Map,3)) +y = ArrayBuffer((Linked,1), (Hash,2), (Map,3)) +x equals y: true, y equals x: true + +x = ArrayBuffer((Linked,1), (Hash,2), (Map,3)) +y = List((Linked,1), (Hash,2), (Map,3)) +x equals y: true, y equals x: true + +x = Set(layers, buffers, title) +y = Set(layers, buffers, title) +x equals y: true, y equals x: true + +x = ArrayBuffer(layers, buffers, title) +y = ArrayBuffer(layers, buffers, title) +x equals y: true, y equals x: true + +x = ArrayBuffer(layers, buffers, title) +y = List(layers, buffers, title) +x equals y: true, y equals x: true + x = ListBuffer(white, black) y = ListBuffer(white, black) x equals y: true, y equals x: true diff --git a/test/files/jvm/serialization-new.scala b/test/files/jvm/serialization-new.scala index 91eb52928f..1522fc8e27 100644 --- a/test/files/jvm/serialization-new.scala +++ b/test/files/jvm/serialization-new.scala @@ -285,8 +285,8 @@ object Test3_mutable { import scala.reflect.ClassTag import scala.collection.mutable.{ ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList, - HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue, - Stack, StringBuilder, WrappedArray, TreeSet} + HashMap, HashSet, History, LinkedHashMap, LinkedHashSet, LinkedList, ListBuffer, + Publisher, Queue, Stack, StringBuilder, WrappedArray, TreeSet} import scala.collection.concurrent.TrieMap // in alphabetic order @@ -346,6 +346,26 @@ object Test3_mutable { val h1 = new History[String, Int] val _h1: History[String, Int] = read(write(h1)) check(h1, _h1) + + // LinkedHashMap + { val lhm1 = new LinkedHashMap[String, Int] + val list = List(("Linked", 1), ("Hash", 2), ("Map", 3)) + lhm1 ++= list.iterator + val _lhm1: LinkedHashMap[String, Int] = read(write(lhm1)) + check(lhm1, _lhm1) + check(lhm1.toSeq, _lhm1.toSeq) // check elements order + check(lhm1.toSeq, list) // check elements order + } + + // LinkedHashSet + { val lhs1 = new LinkedHashSet[String] + val list = List("layers", "buffers", "title") + lhs1 ++= list.iterator + val _lhs1: LinkedHashSet[String] = read(write(lhs1)) + check(lhs1, _lhs1) + check(lhs1.toSeq, _lhs1.toSeq) // check elements order + check(lhs1.toSeq, list) // check elements order + } /* // LinkedList val ll1 = new LinkedList[Int](2, null) diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check index fa51c6a879..f886cfe29c 100644 --- a/test/files/jvm/serialization.check +++ b/test/files/jvm/serialization.check @@ -168,6 +168,30 @@ x = History() y = History() x equals y: true, y equals x: true +x = Map(Linked -> 1, Hash -> 2, Map -> 3) +y = Map(Linked -> 1, Hash -> 2, Map -> 3) +x equals y: true, y equals x: true + +x = ArrayBuffer((Linked,1), (Hash,2), (Map,3)) +y = ArrayBuffer((Linked,1), (Hash,2), (Map,3)) +x equals y: true, y equals x: true + +x = ArrayBuffer((Linked,1), (Hash,2), (Map,3)) +y = List((Linked,1), (Hash,2), (Map,3)) +x equals y: true, y equals x: true + +x = Set(layers, buffers, title) +y = Set(layers, buffers, title) +x equals y: true, y equals x: true + +x = ArrayBuffer(layers, buffers, title) +y = ArrayBuffer(layers, buffers, title) +x equals y: true, y equals x: true + +x = ArrayBuffer(layers, buffers, title) +y = List(layers, buffers, title) +x equals y: true, y equals x: true + x = ListBuffer(white, black) y = ListBuffer(white, black) x equals y: true, y equals x: true diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala index 9c2f2acdbf..34b64938b4 100644 --- a/test/files/jvm/serialization.scala +++ b/test/files/jvm/serialization.scala @@ -285,8 +285,8 @@ object Test3_mutable { import scala.reflect.ClassManifest import scala.collection.mutable.{ ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList, - HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue, - Stack, StringBuilder, WrappedArray, TreeSet} + HashMap, HashSet, History, LinkedHashMap, LinkedHashSet, LinkedList, ListBuffer, + Publisher, Queue, Stack, StringBuilder, WrappedArray, TreeSet} import scala.collection.concurrent.TrieMap // in alphabetic order @@ -346,6 +346,26 @@ object Test3_mutable { val h1 = new History[String, Int] val _h1: History[String, Int] = read(write(h1)) check(h1, _h1) + + // LinkedHashMap + { val lhm1 = new LinkedHashMap[String, Int] + val list = List(("Linked", 1), ("Hash", 2), ("Map", 3)) + lhm1 ++= list.iterator + val _lhm1: LinkedHashMap[String, Int] = read(write(lhm1)) + check(lhm1, _lhm1) + check(lhm1.toSeq, _lhm1.toSeq) // check elements order + check(lhm1.toSeq, list) // check elements order + } + + // LinkedHashSet + { val lhs1 = new LinkedHashSet[String] + val list = List("layers", "buffers", "title") + lhs1 ++= list.iterator + val _lhs1: LinkedHashSet[String] = read(write(lhs1)) + check(lhs1, _lhs1) + check(lhs1.toSeq, _lhs1.toSeq) // check elements order + check(lhs1.toSeq, list) // check elements order + } /* // LinkedList val ll1 = new LinkedList[Int](2, null) diff --git a/test/files/lib/javac-artifacts.jar.desired.sha1 b/test/files/lib/javac-artifacts.jar.desired.sha1 new file mode 100644 index 0000000000..8dbbc1d451 --- /dev/null +++ b/test/files/lib/javac-artifacts.jar.desired.sha1 @@ -0,0 +1 @@ +c5788c5e518eb267445c5a995fd98b2210f90a58 ?javac-artifacts.jar diff --git a/test/files/neg/static-annot.check b/test/files/neg/static-annot.check deleted file mode 100644 index c98e7d9658..0000000000 --- a/test/files/neg/static-annot.check +++ /dev/null @@ -1,22 +0,0 @@ -static-annot.scala:8: error: Only members of top-level objects and their nested objects can be annotated with @static. - @static val bar = 1 - ^ -static-annot.scala:27: error: @static annotated field bar has the same name as a member of class Conflicting - @static val bar = 1 - ^ -static-annot.scala:37: error: The @static annotation is only allowed on public members. - @static private val bar = 1 - ^ -static-annot.scala:38: error: The @static annotation is only allowed on public members. - @static private val baz = 2 - ^ -static-annot.scala:39: error: The @static annotation is not allowed on lazy members. - @static lazy val bam = 3 - ^ -static-annot.scala:52: error: The @static annotation is not allowed on method definitions. - @static def x = 42 - ^ -static-annot.scala:14: error: Only members of top-level objects and their nested objects can be annotated with @static. - @static val blah = 2 - ^ -7 errors found diff --git a/test/files/neg/static-annot.scala b/test/files/neg/static-annot.scala deleted file mode 100644 index c0b5ed30d8..0000000000 --- a/test/files/neg/static-annot.scala +++ /dev/null @@ -1,53 +0,0 @@ - - -import annotation.static - - - -class StaticInClass { - @static val bar = 1 -} - - -class NestedObjectInClass { - object Nested { - @static val blah = 2 - } -} - - -object NestedObjectInObject { - object Nested { - @static val succeed = 3 - } -} - - -object Conflicting { - @static val bar = 1 -} - - -class Conflicting { - val bar = 45 -} - - -object PrivateProtectedLazy { - @static private val bar = 1 - @static private val baz = 2 - @static lazy val bam = 3 -} - - -class PrivateProtectedLazy { - println(PrivateProtectedLazy.bar) - println(PrivateProtectedLazy.baz) - println(PrivateProtectedLazy.bam) -} - - -class StaticDef { - // this should not crash the compiler - @static def x = 42 -} diff --git a/test/files/neg/t4581.check b/test/files/neg/t4581.check deleted file mode 100644 index e69de29bb2..0000000000 --- a/test/files/neg/t4581.check +++ /dev/null diff --git a/test/files/neg/t4581/static-declaration_1.scala b/test/files/neg/t4581/static-declaration_1.scala deleted file mode 100644 index f9a66b29c1..0000000000 --- a/test/files/neg/t4581/static-declaration_1.scala +++ /dev/null @@ -1,14 +0,0 @@ - - - - - -object Constants { - import scala.annotation.static - @static val Const: Int = 0 // should generate a static final field - @static final val FinalConst: Int = 0 // ditto - @static var MutableField: Int = 0 // should not be final -} - - - diff --git a/test/files/neg/t4581/static_2.java b/test/files/neg/t4581/static_2.java deleted file mode 100644 index 2fd5bf1d82..0000000000 --- a/test/files/neg/t4581/static_2.java +++ /dev/null @@ -1,15 +0,0 @@ - - - - -public class static_2 { - public static void main(String[] args) { - Constants.Const = 17; - Constants.FinalConst = 99; - Constants.MutableField = 199; - } -} - - - - diff --git a/test/files/pos/t6294.scala b/test/files/pos/t6294.scala deleted file mode 100644 index c6d39a9cc8..0000000000 --- a/test/files/pos/t6294.scala +++ /dev/null @@ -1,14 +0,0 @@ - - - -object A { - @annotation.static final val x = 123 -} - - -object B { - println(A.x) -} - - - diff --git a/test/files/run/collections.check b/test/files/run/collections.check index b87a5998c5..c24150b24d 100644 --- a/test/files/run/collections.check +++ b/test/files/run/collections.check @@ -2,6 +2,10 @@ test1: 14005 test2: 25005003, iters = 5000 test3: 25005003 +***** mutable.LinkedHashSet: +test1: 14005 +test2: 25005003, iters = 5000 +test3: 25005003 ***** immutable.Set: test1: 14005 test2: 25005003, iters = 5000 @@ -18,6 +22,10 @@ test3: 25005003 test1: 14005 test2: 25005003, iters = 5000 test3: 25005003 +***** mutable.LinkedHashMap: +test1: 14005 +test2: 25005003, iters = 5000 +test3: 25005003 ***** immutable.Map: test1: 14005 test2: 25005003, iters = 5000 diff --git a/test/files/run/collections.scala b/test/files/run/collections.scala index 60f0765e6a..69c40fae80 100644 --- a/test/files/run/collections.scala +++ b/test/files/run/collections.scala @@ -106,10 +106,12 @@ object Test extends App { } test("mutable.HashSet", new mutable.HashSet[Int], 5000) + test("mutable.LinkedHashSet", new mutable.LinkedHashSet[Int], 5000) test("immutable.Set", immutable.Set[Int](), 5000) test("immutable.ListSet", new immutable.ListSet[Int], 5000) test("immutable.TreeSet", new immutable.TreeSet[Int], 5000) test("mutable.HashMap", new mutable.HashMap[Int, Int], 5000) + test("mutable.LinkedHashMap", new mutable.LinkedHashMap[Int, Int], 5000) test("immutable.Map", immutable.Map[Int, Int](), 5000) test("immutable.TreeMap", new immutable.TreeMap[Int, Int], 5000) test("immutable.ListMap", new immutable.ListMap[Int, Int], 3000) diff --git a/test/files/run/colltest.check b/test/files/run/colltest.check index 1ad81a1350..e5bb013ed7 100644 --- a/test/files/run/colltest.check +++ b/test/files/run/colltest.check @@ -5,3 +5,4 @@ false true false succeeded for 10 iterations. +succeeded for 10 iterations. diff --git a/test/files/run/colltest.scala b/test/files/run/colltest.scala index ecd234bdd1..703e94a3c7 100644 --- a/test/files/run/colltest.scala +++ b/test/files/run/colltest.scala @@ -61,5 +61,6 @@ object Test extends App { } t3954 - new TestSet(HashSet.empty, new scala.collection.mutable.LinkedHashSet) + new TestSet(HashSet.empty, new LinkedHashSet) + new TestSet(new ImmutableSetAdaptor(collection.immutable.Set.empty[Int]), new LinkedHashSet) } diff --git a/test/files/run/colltest1.check b/test/files/run/colltest1.check index 7377174281..5ec6286d9e 100644 --- a/test/files/run/colltest1.check +++ b/test/files/run/colltest1.check @@ -107,3 +107,5 @@ List((A,A), (B,B), (C,C), (D,D), (E,E), (F,F), (G,G), (H,H), (I,I), (J,J), (K,K) List((A,A), (B,B), (C,C), (D,D), (E,E), (F,F), (G,G), (H,H), (I,I), (J,J), (K,K), (L,L), (M,M), (N,N), (O,O), (P,P), (Q,Q), (R,R), (S,S), (T,T), (U,U), (V,V), (W,W), (X,X), (Y,Y), (Z,Z)) List((A,A), (B,B), (C,C), (D,D), (E,E), (F,F), (G,G), (H,H), (I,I), (J,J), (K,K), (L,L), (M,M), (N,N), (O,O), (P,P), (Q,Q), (R,R), (S,S), (T,T), (U,U), (V,V), (W,W), (X,X), (Y,Y), (Z,Z)) List((A,A), (B,B), (C,C), (D,D), (E,E), (F,F), (G,G), (H,H), (I,I), (J,J), (K,K), (L,L), (M,M), (N,N), (O,O), (P,P), (Q,Q), (R,R), (S,S), (T,T), (U,U), (V,V), (W,W), (X,X), (Y,Y), (Z,Z)) +List((A,A), (B,B), (C,C), (D,D), (E,E), (F,F), (G,G), (H,H), (I,I), (J,J), (K,K), (L,L), (M,M), (N,N), (O,O), (P,P), (Q,Q), (R,R), (S,S), (T,T), (U,U), (V,V), (W,W), (X,X), (Y,Y), (Z,Z)) +List((A,A), (B,B), (C,C), (D,D), (E,E), (F,F), (G,G), (H,H), (I,I), (J,J), (K,K), (L,L), (M,M), (N,N), (O,O), (P,P), (Q,Q), (R,R), (S,S), (T,T), (U,U), (V,V), (W,W), (X,X), (Y,Y), (Z,Z)) diff --git a/test/files/run/colltest1.scala b/test/files/run/colltest1.scala index 1cbd932222..54adeb7cda 100644 --- a/test/files/run/colltest1.scala +++ b/test/files/run/colltest1.scala @@ -226,6 +226,7 @@ object Test extends App { setTest(mutable.Set()) setTest(immutable.Set()) setTest(mutable.HashSet()) + setTest(mutable.LinkedHashSet()) setTest(immutable.HashSet()) mapTest(Map()) @@ -233,5 +234,6 @@ object Test extends App { mapTest(immutable.Map()) mapTest(immutable.TreeMap()) mutableMapTest(mutable.HashMap()) + mutableMapTest(mutable.LinkedHashMap()) mapTest(immutable.HashMap()) } diff --git a/test/files/run/reflection-java-annotations.check b/test/files/run/reflection-java-annotations.check index 84cfd03358..53c53cfbcc 100644 --- a/test/files/run/reflection-java-annotations.check +++ b/test/files/run/reflection-java-annotations.check @@ -1,22 +1 @@ -Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala>
-
-scala> import scala.reflect.runtime.universe._
-import scala.reflect.runtime.universe._
-
-scala> val sym = typeOf[Foo].typeSymbol
-sym: reflect.runtime.universe.Symbol = class Foo
-
-scala> sym.typeSignature
-res0: reflect.runtime.universe.Type = java.lang.Object{def <init>(): Foo}
-
-scala> sym.getAnnotations foreach (_.javaArgs)
-
-scala> println(sym.getAnnotations)
-List(ComplexAnnotation(v1 = 1, v10 = "hello", v101 = [101, 101], v102 = [102, 102], v103 = ['g', 'g'], v104 = [104, 104], v105 = [105L, 105L], v106 = [106.0, 106.0], v107 = [107.0, 107.0], v108 = [false, true], v11 = classOf[Foo], v110 = ["hello", "world"], v111 = [classOf[SimpleAnnotation], classOf[ComplexAnnotation]], v113 = [SimpleAnnotation(v1 = 21, v10 = "world2", v11 = classOf[ComplexAnnotation], v2 = 22, v3 = '\027', v4 = 24, v5 = 25L, v6 = 26.0, v7 = 27.0, v8 = false)], v13 = SimpleAnnotation(v1 = 11, v10 = "world1", v11 = classOf[SimpleAnnotation], v2 = 12, v3 = '\r', v4 = 14, v5 = 15L, v6 = 16.0, v7 = 17.0, v8 = false), v2 = 2, v3 = '\03', v4 = 4, v5 = 5L, v6 = 6.0, v7 = 7.0, v8 = false))
-
-scala>
-
-scala>
+List(JavaComplexAnnotation(v1 = 1, v10 = "hello", v101 = [101, 101], v102 = [102, 102], v103 = ['g', 'g'], v104 = [104, 104], v105 = [105L, 105L], v106 = [106.0, 106.0], v107 = [107.0, 107.0], v108 = [false, true], v11 = classOf[JavaAnnottee], v110 = ["hello", "world"], v111 = [classOf[JavaSimpleAnnotation], classOf[JavaComplexAnnotation]], v112 = [FOO, BAR], v113 = [JavaSimpleAnnotation(v1 = 21, v10 = "world2", v11 = classOf[JavaComplexAnnotation], v12 = BAR, v2 = 22, v3 = '\027', v4 = 24, v5 = 25L, v6 = 26.0, v7 = 27.0, v8 = false)], v12 = FOO, v13 = JavaSimpleAnnotation(v1 = 11, v10 = "world1", v11 = classOf[JavaSimpleAnnotation], v12 = FOO, v2 = 12, v3 = '\r', v4 = 14, v5 = 15L, v6 = 16.0, v7 = 17.0, v8 = false), v2 = 2, v3 = '\03', v4 = 4, v5 = 5L, v6 = 6.0, v7 = 7.0, v8 = false)) diff --git a/test/files/run/reflection-java-annotations.jar.desired.sha1 b/test/files/run/reflection-java-annotations.jar.desired.sha1 deleted file mode 100644 index 430e7626e6..0000000000 --- a/test/files/run/reflection-java-annotations.jar.desired.sha1 +++ /dev/null @@ -1 +0,0 @@ -c35876a529c6be33bdda7b3f48ac8ae800d2f36a ?reflection-java-annotations.jar diff --git a/test/files/run/reflection-java-annotations.scala b/test/files/run/reflection-java-annotations.scala index 4a4fe2572d..0b16c0d103 100644 --- a/test/files/run/reflection-java-annotations.scala +++ b/test/files/run/reflection-java-annotations.scala @@ -1,20 +1,7 @@ -import scala.tools.partest._ -import scala.tools.nsc.Settings - -object Test extends ReplTest { - def code = """ - import scala.reflect.runtime.universe._ - val sym = typeOf[Foo].typeSymbol - sym.typeSignature - sym.getAnnotations foreach (_.javaArgs) - println(sym.getAnnotations) - """ - - override def transformSettings(settings: Settings): Settings = { - val thisFile = testPath.jfile.getAbsolutePath - val javaCompiledAnnotationsJar = (thisFile stripSuffix "scala") + "jar" - val classpath = List(sys.props("partest.lib"), sys.props("partest.reflect"), sys.props("partest.comp"), javaCompiledAnnotationsJar) mkString sys.props("path.separator") - settings.processArguments(List("-cp", classpath), true) - settings - } +object Test extends App { + import scala.reflect.runtime.universe._ + val sym = typeOf[JavaAnnottee].typeSymbol + sym.typeSignature + sym.getAnnotations foreach (_.javaArgs) + println(sym.getAnnotations) }
\ No newline at end of file diff --git a/test/files/run/reflection-java-crtp.check b/test/files/run/reflection-java-crtp.check new file mode 100644 index 0000000000..3e5a77e93a --- /dev/null +++ b/test/files/run/reflection-java-crtp.check @@ -0,0 +1 @@ +(type E,type E,true) diff --git a/test/files/run/reflection-java-crtp.scala b/test/files/run/reflection-java-crtp.scala new file mode 100644 index 0000000000..260d3540dc --- /dev/null +++ b/test/files/run/reflection-java-crtp.scala @@ -0,0 +1,8 @@ +object Test extends App { + import scala.reflect.runtime.universe._ + val enum = typeOf[JavaSimpleEnumeration].baseClasses(1).asClass + // make sure that the E's in Enum<E extends Enum<E>> are represented by the same symbol + val e1 = enum.typeParams(0).asType + val TypeBounds(_, TypeRef(_, _, List(TypeRef(_, e2: TypeSymbol, _)))) = e1.typeSignature + println(e1, e2, e1 eq e2) +}
\ No newline at end of file diff --git a/test/files/run/static-annot-repl.check b/test/files/run/static-annot-repl.check deleted file mode 100644 index 3a1532b823..0000000000 --- a/test/files/run/static-annot-repl.check +++ /dev/null @@ -1,38 +0,0 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> - -scala> import annotation.static -import annotation.static - -scala> @static var x1 = 42 -x1: Int = 42 - -scala> @static val x2 = 43 -x2: Int = 43 - -scala> @static def x3 = 44 -<console>:8: error: The @static annotation is not allowed on method definitions. - @static def x3 = 44 - ^ - -scala> x1 -res0: Int = 42 - -scala> x2 -res1: Int = 43 - -scala> x3 -<console>:9: error: not found: value x3 - x3 - ^ - -scala> class Test { - @static def x = 42 -} -<console>:9: error: The @static annotation is not allowed on method definitions. - @static def x = 42 - ^ - -scala>
\ No newline at end of file diff --git a/test/files/run/static-annot-repl.scala b/test/files/run/static-annot-repl.scala deleted file mode 100644 index 1d2e9b2d7e..0000000000 --- a/test/files/run/static-annot-repl.scala +++ /dev/null @@ -1,22 +0,0 @@ - - - -import scala.tools.partest.ReplTest - - - -object Test extends ReplTest { - def code = """ -import annotation.static -@static var x1 = 42 -@static val x2 = 43 -@static def x3 = 44 -x1 -x2 -x3 -class Test { - @static def x = 42 -} -""" - -} diff --git a/test/files/run/static-annot/field.scala b/test/files/run/static-annot/field.scala deleted file mode 100644 index 8408a51800..0000000000 --- a/test/files/run/static-annot/field.scala +++ /dev/null @@ -1,252 +0,0 @@ - - - -import java.lang.reflect.Modifier -import annotation.static -import reflect._ - - - -/* TEST 1 */ - -/* A @static-annotated field in the companion object should yield - * a static field in its companion class. - */ -object Foo { - @static val bar = 17 -} - - -class Foo - - -trait Check { - def checkStatic(cls: Class[_]) { - cls.getDeclaredFields.find(_.getName == "bar") match { - case Some(f) => - assert(Modifier.isStatic(f.getModifiers), "no static modifier") - case None => - assert(false, "no static field bar in class") - } - } - - def test(): Unit -} - - -object Test1 extends Check { - def test() { - checkStatic(classOf[Foo]) - assert(Foo.bar == 17, "Companion object field should be 17.") - } -} - - -/* TEST 2 */ - -class Foo2 - - -/** The order of declaring the class and its companion is inverted now. */ -object Foo2 { - @static val bar = 199 -} - - -object Test2 extends Check { - def test() { - checkStatic(Class.forName("Foo3")) - assert(Foo3.bar == 1984, "Companion object field should be 1984.") - } -} - - -/* TEST 3 */ - -/** The case where there is no explicit companion class */ -object Foo3 { - @static val bar = 1984 -} - - -object Test3 extends Check { - def test() { - checkStatic(Class.forName("Foo3")) - assert(Foo3.bar == 1984, "Companion object field should be 1984.") - } -} - - -/* TEST 4 */ - -/** We want to be able to generate atomic reference field updaters on the companion object - * so that they are created only once per class declaration, but we want them to actually - * be initialize __in the static initializer of the class itself__. - * This is extremely important, because otherwise the creation of the ARFU fails, since it uses - * trickery to detect the caller and compare it to the owner of the field being modified. - * Previously, this used to be circumvented through the use of Java base classes. A pain. - */ -class ArfuTarget { - @volatile var strfield = ArfuTarget.STR - - def CAS(ov: String, nv: String): Boolean = { - ArfuTarget.arfu.compareAndSet(this, ov, nv) - } -} - - -object ArfuTarget { - @static val arfu = java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(classOf[ArfuTarget], classOf[String], "strfield") - val STR = "Some string" -} - - -object Test4 extends Check { - def checkArfu() { - val at = new ArfuTarget - assert(at.strfield == ArfuTarget.STR) - at.CAS(ArfuTarget.STR, null) - assert(at.strfield == null) - } - - def test() { - checkArfu() - } -} - - -/* TEST 5 */ - -/** Although our main use-case is to use final static fields, we should be able to use non-final too. - * Here we set the static field of the class by using the setters in the companion object. - * It is legal to do so using the reference to `Foo` directly (in which case the callsites - * are rewritten to access the static field directly), or through an interface `Var` (in - * which case the getter and the setter for `field` access the static field in `Var`). - */ -trait Var { - var field: Int -} - -object VarHolder extends Var { - @static var field = 1 -} - - -object Test5 extends Check { - def test() { - assert(VarHolder.field == 1) - VarHolder.field = 2 - assert(VarHolder.field == 2) - val vh: Var = VarHolder - vh.field = 3 - assert(vh.field == 3) - } -} - - -/* TEST 6 */ - -/** Here we test flattening the static ctor body and changing the owners of local definitions. */ -object Foo6 { - var companionField = 101 - @static val staticField = { - val intermediate = companionField + 1 - intermediate * 2 - } -} - - -object Test6 extends Check { - def test() { - assert(Foo6.staticField == 204) - } -} - - - -/* TEST 7 */ - -/** Here we test objects nested in top-level objects */ -object Foo7 { - object AndHisFriend { - @static val bar = "string" - } - class AndHisFriend - - object AndHisLonelyFriend { - @static val bar = "another" - } -} - - -object Test7 extends Check { - def test() { - checkStatic(classOf[Foo7.AndHisFriend]) - assert(Foo7.AndHisFriend.bar == "string") - - checkStatic(Class.forName("Foo7$AndHisLonelyFriend")) - assert(Foo7.AndHisLonelyFriend.bar == "another") - } -} - - - -/* TEST 8 */ - -object Foo8 { - @static val field = 7 - - val function: () => Int = () => { - field + 1 - } - - val anon = new Runnable { - def run() { - assert(field == 7, "runnable asserting field is 7") - } - } - - @static var mutable = 10 - - val mutation: () => Unit = () => { - mutable += 1 - } -} - -object Test8 { - def test() { - assert(Foo8.function() == 8, "function must return 8") - Foo8.anon.run() - assert(Foo8.mutable == 10, "mutable is 10") - Foo8.mutation() - assert(Foo8.mutable == 11, "mutable is 11") - Foo8.mutation() - assert(Foo8.mutable == 12, "mutable is 12") - } -} - - - - -/* main */ - -object Test { - - def main(args: Array[String]) { - Test1.test() - Test2.test() - Test3.test() - Test4.test() - Test5.test() - Test6.test() - Test7.test() - Test8.test() - } - -} - - - - - - diff --git a/test/files/run/t5770.check b/test/files/run/t5770.check new file mode 100644 index 0000000000..eeb1d55321 --- /dev/null +++ b/test/files/run/t5770.check @@ -0,0 +1,10 @@ +1
+2
+3
+4
+5
+6
+7
+8
+9
+10
diff --git a/test/files/run/t5770.scala b/test/files/run/t5770.scala new file mode 100644 index 0000000000..b6c9236844 --- /dev/null +++ b/test/files/run/t5770.scala @@ -0,0 +1,25 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect._ + +object Test extends App { + var i = 0 + val action = reify { i += 1; println(i) }.tree + + val tb1 = cm.mkToolBox() + tb1.eval(action) + tb1.eval(action) + tb1.eval(action) + tb1.frontEnd.reset() + tb1.eval(action) + tb1.eval(action) + + val tb2 = cm.mkToolBox() + tb2.eval(action) + tb2.frontEnd.reset() + tb2.eval(action) + tb2.eval(action) + tb2.frontEnd.reset() + tb2.eval(action) + tb2.eval(action) +} diff --git a/test/files/run/t6236.check b/test/files/run/t6236.check deleted file mode 100644 index a0a2e88d0a..0000000000 --- a/test/files/run/t6236.check +++ /dev/null @@ -1,2 +0,0 @@ -353 -353
\ No newline at end of file diff --git a/test/files/run/t6236/file_1.scala b/test/files/run/t6236/file_1.scala deleted file mode 100644 index 92d22799fc..0000000000 --- a/test/files/run/t6236/file_1.scala +++ /dev/null @@ -1,9 +0,0 @@ - - -package p { - object y { - object x { - @scala.annotation.static val foo: Int = 353 - } - } -} diff --git a/test/files/run/t6236/file_2.scala b/test/files/run/t6236/file_2.scala deleted file mode 100644 index 51823004ca..0000000000 --- a/test/files/run/t6236/file_2.scala +++ /dev/null @@ -1,10 +0,0 @@ - - - -object Test { - def main(args: Array[String]): Unit = { - println(p.y.x.foo) - println(p.y.x.foo) - } -} - diff --git a/test/files/run/t6287.check b/test/files/run/t6287.check new file mode 100644 index 0000000000..2a783704a2 --- /dev/null +++ b/test/files/run/t6287.check @@ -0,0 +1,3 @@ +Vector(2, 3, 4)
+Vector(2, 3, 4)
+Vector(2, 3, 4)
diff --git a/test/files/run/t6287.scala b/test/files/run/t6287.scala new file mode 100644 index 0000000000..0c75d1081b --- /dev/null +++ b/test/files/run/t6287.scala @@ -0,0 +1,11 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect._ + +object Test extends App { + val tb = cm.mkToolBox() + val t1 = tb.parse("1 to 3 map (_+1)") + println(tb.eval(t1)) + println(tb.eval(t1)) + println(tb.eval(t1)) +}
\ No newline at end of file |