diff options
233 files changed, 2690 insertions, 1747 deletions
@@ -204,7 +204,9 @@ INITIALISATION <property name="scalac.args.quickonly" value=""/> <property name="scalac.args.all" value="${scalac.args} ${scalac.args.optimise}"/> - <property name="scalac.args.quick" value="${scalac.args.all} ${scalac.args.quickonly}"/> + <echo message="Using scalac.args.all: ${scalac.args.all}"/> + <echo message="Using javac.args: ${javac.args}"/> + <property name="scalac.args.quick" value="${scalac.args.all} ${scalac.args.quickonly}"/> <!-- Setting-up Ant contrib tasks --> <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant/ant-contrib.jar"/> <!-- This is the start time for the distribution --> @@ -228,18 +230,18 @@ INITIALISATION <!-- Both clauses of the conditional set svn.number --> <if> - <equals arg1="${svn.number.svn}" arg2="0" /> - <then> + <equals arg1="${svn.number.svn}" arg2="0" /> + <then> <!-- Finding SVN revision, git style --> - <exec osfamily="unix" executable="tools/git-get-rev" outputproperty="svn.number.git" failifexecutionfails="false" /> - <propertyregex - property="svn.number" input="${svn.number.git}" select="\1" - regexp="\D*?(\d+)" - defaultValue="0"/> - </then> - <else> - <property name="svn.number" value="${svn.number.svn}" /> - </else> + <exec osfamily="unix" executable="tools/git-get-rev" outputproperty="svn.number.git" failifexecutionfails="false" /> + <propertyregex + property="svn.number" input="${svn.number.git}" select="\1" + regexp="\D*?(\d+)" + defaultValue="0"/> + </then> + <else> + <property name="svn.number" value="${svn.number.svn}" /> + </else> </if> <property name="init.avail" value="yes"/> @@ -621,15 +623,15 @@ QUICK BUILD (QUICK) file="${src.dir}/continuations/plugin/scalac-plugin.xml" todir="${build-quick.dir}/classes/continuations-plugin"/> <!-- not very nice to create jar here but needed to load plugin --> - <mkdir dir="${build-quick.dir}/plugins"/> - <jar destfile="${build-quick.dir}/plugins/continuations.jar"> + <mkdir dir="${build-quick.dir}/misc/scala-devel/plugins"/> + <jar destfile="${build-quick.dir}/misc/scala-devel/plugins/continuations.jar"> <fileset dir="${build-quick.dir}/classes/continuations-plugin"/> </jar> <!-- might split off library part into its own ant target --> <scalacfork destdir="${build-quick.dir}/classes/library" compilerpathref="locker.classpath" - params="${scalac.args.quick} -Xpluginsdir ${build-quick.dir}/plugins -Xplugin-require:continuations -P:continuations:enable" + params="${scalac.args.quick} -Xpluginsdir ${build-quick.dir}/misc/scala-devel/plugins -Xplugin-require:continuations -P:continuations:enable" srcdir="${src.dir}/continuations/library" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -850,13 +852,13 @@ PACKED QUICK BUILD (PACK) <target name="pack.pre-plugins" depends="pack.comp"> <uptodate property="pack.plugins.available" - targetfile="${build-pack.dir}/plugins/continuations.jar" + targetfile="${build-pack.dir}/misc/scala-devel/plugins/continuations.jar" srcfile="${build-quick.dir}/plugins.complete"/> </target> <target name="pack.plugins" depends="pack.pre-plugins" unless="pack.plugins.available"> - <mkdir dir="${build-pack.dir}/plugins"/> - <jar destfile="${build-pack.dir}/plugins/continuations.jar"> + <mkdir dir="${build-pack.dir}/misc/scala-devel/plugins"/> + <jar destfile="${build-pack.dir}/misc/scala-devel/plugins/continuations.jar"> <fileset dir="${build-quick.dir}/classes/continuations-plugin"/> </jar> </target> @@ -931,15 +933,6 @@ PACKED QUICK BUILD (PACK) <chmod perm="ugo+rx" file="${build-pack.dir}/bin/scaladoc"/> <chmod perm="ugo+rx" file="${build-pack.dir}/bin/fsc"/> <chmod perm="ugo+rx" file="${build-pack.dir}/bin/scalap"/> - - <mkdir dir="${build-pack.dir}/etc"/> - <exec osfamily="unix" executable="${build-pack.dir}/bin/scala" output="${build-pack.dir}/etc/scala_completion.sh" failifexecutionfails="false" > - <arg line="scala.tools.util.BashCompletion" /> - </exec> - <!-- <exec append="true" osfamily="unix" executable="${build-pack.dir}/bin/scala" output="${build-pack.dir}/etc/scala_completion.sh" failifexecutionfails="false" > - <arg line="scala.tools.partest.PartestSpecDryRun" /> - </exec> --> - <touch file="${build-pack.dir}/bin.complete" verbose="no"/> </target> @@ -1115,7 +1108,7 @@ BOOTSTRAPPING BUILD (STRAP) <scalacfork destdir="${build-strap.dir}/classes/continuations-plugin" compilerpathref="pack.classpath" - params="${scalac.args.quick}" + params="${scalac.args.all}" srcdir="${src.dir}/continuations/plugin" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1128,15 +1121,15 @@ BOOTSTRAPPING BUILD (STRAP) file="${src.dir}/continuations/plugin/scalac-plugin.xml" todir="${build-strap.dir}/classes/continuations-plugin"/> <!-- not very nice to create jar here but needed to load plugin --> - <mkdir dir="${build-strap.dir}/plugins"/> - <jar destfile="${build-strap.dir}/plugins/continuations.jar"> + <mkdir dir="${build-strap.dir}/misc/scala-devel/plugins"/> + <jar destfile="${build-strap.dir}/misc/scala-devel/plugins/continuations.jar"> <fileset dir="${build-strap.dir}/classes/continuations-plugin"/> </jar> <!-- might split off library part into its own ant target --> <scalacfork destdir="${build-strap.dir}/classes/library" compilerpathref="pack.classpath" - params="${scalac.args.quick} -Xpluginsdir ${build-quick.dir}/plugins -Xplugin-require:continuations -P:continuations:enable" + params="${scalac.args.all} -Xpluginsdir ${build-quick.dir}/misc/scala-devel/plugins -Xplugin-require:continuations -P:continuations:enable" srcdir="${src.dir}/continuations/library" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1504,34 +1497,28 @@ BOOTRAPING TEST AND TEST SUITE </same> </target> - <target name="test.suite.clean.checkinit"> - <antcall target="all.clean" /> - <antcall target="test.suite" inheritAll="false"> - <param name="scalac.args.optimise" value="-Xcheckinit" /> - <param name="partest.scalacopts" value="-Xcheckinit" /> - </antcall> - </target> - <target name="test.suite" depends="pack.done"> - <partest classpathref="pack.classpath"> - <env key="PATH" path="${build-pack.dir}/bin:${env.PATH}" /> - <sysproperty key="partest.srcdir" value="files" /> - <syspropertyset> - <propertyref prefix="partest"/> - </syspropertyset> + <partest classpathref="pack.classpath"> + <env key="PATH" path="${build-pack.dir}/bin:${env.PATH}" /> + <sysproperty key="partest.srcdir" value="files" /> + <sysproperty key="partest.scalacopts" value="${scalac.args.all}" /> + <sysproperty key="partest.javacopts" value="${javac.args}" /> + <syspropertyset> + <propertyref prefix="partest"/> + </syspropertyset> </partest> </target> <target name="test.continuations.suite" depends="pack.done"> - <partest classpathref="pack.classpath"> - <env key="PATH" path="${build-pack.dir}/bin:${env.PATH}" /> - <sysproperty key="partest.srcdir" value="continuations" /> - <sysproperty key="partest.scalacopts" value="${scalac.args.optimise} -Xpluginsdir ${build-quick.dir}/plugins -Xplugin-require:continuations -P:continuations:enable" /> - <sysproperty key="partest.runsets" value="neg run" /> - <syspropertyset> - <propertyref prefix="partest"/> - </syspropertyset> - </partest> + <partest classpathref="pack.classpath"> + <env key="PATH" path="${build-pack.dir}/bin:${env.PATH}" /> + <sysproperty key="partest.srcdir" value="continuations" /> + <sysproperty key="partest.scalacopts" value="${scalac.args.optimise} -Xpluginsdir ${build-quick.dir}/misc/scala-devel/plugins -Xplugin-require:continuations -P:continuations:enable" /> + <sysproperty key="partest.runsets" value="neg run" /> + <syspropertyset> + <propertyref prefix="partest"/> + </syspropertyset> + </partest> </target> <target name="test.done" depends="test.suite, test.continuations.suite, test.stability"/> @@ -1558,13 +1545,9 @@ DISTRIBUTION <chmod perm="ugo+rx" file="${dist.dir}/bin/scaladoc"/> <chmod perm="ugo+rx" file="${dist.dir}/bin/fsc"/> <chmod perm="ugo+rx" file="${dist.dir}/bin/scalap"/> - <mkdir dir="${dist.dir}/etc"/> - <copy toDir="${dist.dir}/etc"> - <fileset dir="${build-pack.dir}/etc"/> - </copy> - <mkdir dir="${dist.dir}/plugins"/> - <copy toDir="${dist.dir}/plugins"> - <fileset dir="${build-pack.dir}/plugins"/> + <mkdir dir="${dist.dir}/misc/scala-devel/plugins"/> + <copy toDir="${dist.dir}/misc/scala-devel/plugins"> + <fileset dir="${build-pack.dir}/misc/scala-devel/plugins"/> </copy> </target> @@ -1738,6 +1721,18 @@ FORWARDED TARGETS FOR NIGHTLY BUILDS <ant antfile="${src.dir}/build/pack.xml" target="pack-all.done" inheritall="yes" inheritrefs="yes"/> </target> + <target name="nightly.checkinit"> + <antcall target="nightly-nopt"> + <param name="scalac.args.optimise" value="-Xcheckinit"/> + </antcall> + </target> + + <target name="nightly.checkall"> + <antcall target="nightly-nopt"> + <param name="partest.scalacopts" value="-Ycheck:all"/> + </antcall> + </target> + <!-- =========================================================================== POSITIONS ============================================================================ --> diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index dc48e2f9ae..1e4f27d9cf 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -58217106efbefca262416284da22d8f935c0d5a6 ?scala-compiler.jar +74565ba3b7047eb8873ff8222b904ada4f0c5ccc ?scala-compiler.jar diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1 index 57f522e23d..f977853507 100644 --- a/lib/scala-library-src.jar.desired.sha1 +++ b/lib/scala-library-src.jar.desired.sha1 @@ -1 +1 @@ -084aab3593eb7fbc5ffe68c3af565d258146a85b ?scala-library-src.jar +b194b332aa0a22957de7952222bde3e4af1a5601 ?scala-library-src.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 842de98724..ead85fa756 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -413b018f76f6684e9eb9dc04ea21097e3c59aaf7 ?scala-library.jar +3b7c9f5d65a65e99027d9ddf3ae39fe98251d2f4 ?scala-library.jar diff --git a/src/actors/scala/actors/AbstractActor.scala b/src/actors/scala/actors/AbstractActor.scala index 9cc62a1cde..80b1e76b30 100644 --- a/src/actors/scala/actors/AbstractActor.scala +++ b/src/actors/scala/actors/AbstractActor.scala @@ -14,6 +14,8 @@ package scala.actors * The <code>AbstractActor</code> trait. * * @author Philipp Haller + * + * @define actor actor */ trait AbstractActor extends OutputChannel[Any] with CanReply[Any, Any] { diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala index 491c1eb075..ccd60f666c 100644 --- a/src/actors/scala/actors/Actor.scala +++ b/src/actors/scala/actors/Actor.scala @@ -382,9 +382,12 @@ object Actor extends Combinators { * </ul> * * @author Philipp Haller + * + * @define actor actor + * @define channel actor's mailbox */ @serializable @SerialVersionUID(-781154067877019505L) -trait Actor extends AbstractActor with ReplyReactor with ActorCanReply { +trait Actor extends AbstractActor with ReplyReactor with ActorCanReply with InputChannel[Any] { /* The following two fields are only used when the actor * suspends by blocking its underlying thread, for example, @@ -413,12 +416,6 @@ trait Actor extends AbstractActor with ReplyReactor with ActorCanReply { private[actors] override def makeReaction(fun: () => Unit, handler: PartialFunction[Any, Any], msg: Any): Runnable = new ActorTask(this, fun, handler, msg) - /** - * Receives a message from this actor's mailbox. - * - * @param f a partial function with message patterns and actions - * @return result of processing the received value - */ def receive[R](f: PartialFunction[Any, R]): R = { assert(Actor.self(scheduler) == this, "receive from channel belonging to other actor") @@ -462,14 +459,6 @@ trait Actor extends AbstractActor with ReplyReactor with ActorCanReply { result } - /** - * Receives a message from this actor's mailbox within a certain - * time span. - * - * @param msec the time span before timeout - * @param f a partial function with message patterns and actions - * @return result of processing the received value - */ def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R = { assert(Actor.self(scheduler) == this, "receive from channel belonging to other actor") @@ -556,9 +545,6 @@ trait Actor extends AbstractActor with ReplyReactor with ActorCanReply { super.reactWithin(msec)(handler) } - /** - * Receives the next message from this actor's mailbox. - */ def ? : Any = receive { case x => x } @@ -605,9 +591,6 @@ trait Actor extends AbstractActor with ReplyReactor with ActorCanReply { _state == Actor.State.Terminated } - /** - * Starts this actor. - */ override def start(): Actor = synchronized { if (_state == Actor.State.New) { _state = Actor.State.Runnable diff --git a/src/actors/scala/actors/ActorCanReply.scala b/src/actors/scala/actors/ActorCanReply.scala index 8cba425b4c..fdc3833ec4 100644 --- a/src/actors/scala/actors/ActorCanReply.scala +++ b/src/actors/scala/actors/ActorCanReply.scala @@ -13,7 +13,7 @@ package scala.actors import java.util.concurrent.ExecutionException /** - * The ActorCanReply trait provides message send operations that + * The `ActorCanReply` trait provides message send operations that * may result in a response from the receiver. * * @author Philipp Haller @@ -21,13 +21,6 @@ import java.util.concurrent.ExecutionException private[actors] trait ActorCanReply extends ReactorCanReply { thiz: AbstractActor with ReplyReactor => - /** - * Sends <code>msg</code> to this actor and awaits reply - * (synchronous). - * - * @param msg the message to be sent - * @return the reply - */ override def !?(msg: Any): Any = { val replyCh = new Channel[Any](Actor.self(thiz.scheduler)) thiz.send(msg, replyCh) @@ -36,15 +29,6 @@ private[actors] trait ActorCanReply extends ReactorCanReply { } } - /** - * Sends <code>msg</code> to this actor and awaits reply - * (synchronous) within <code>msec</code> milliseconds. - * - * @param msec the time span before timeout - * @param msg the message to be sent - * @return <code>None</code> in case of timeout, otherwise - * <code>Some(x)</code> where <code>x</code> is the reply - */ override def !?(msec: Long, msg: Any): Option[Any] = { val replyCh = new Channel[Any](Actor.self(thiz.scheduler)) thiz.send(msg, replyCh) @@ -54,13 +38,6 @@ private[actors] trait ActorCanReply extends ReactorCanReply { } } - /** - * Sends <code>msg</code> to this actor and immediately - * returns a future representing the reply value. - * The reply is post-processed using the partial function - * <code>handler</code>. This also allows to recover a more - * precise type for the reply value. - */ override def !![A](msg: Any, handler: PartialFunction[Any, A]): Future[A] = { val ftch = new Channel[A](Actor.self(thiz.scheduler)) thiz.send(msg, new OutputChannel[Any] { @@ -76,10 +53,6 @@ private[actors] trait ActorCanReply extends ReactorCanReply { Futures.fromInputChannel(ftch) } - /** - * Sends <code>msg</code> to this actor and immediately - * returns a future representing the reply value. - */ override def !!(msg: Any): Future[Any] = { val ftch = new Channel[Any](Actor.self(thiz.scheduler)) val linkedChannel = new AbstractActor { diff --git a/src/actors/scala/actors/CanReply.scala b/src/actors/scala/actors/CanReply.scala index 23f0a5319b..99e1169900 100644 --- a/src/actors/scala/actors/CanReply.scala +++ b/src/actors/scala/actors/CanReply.scala @@ -14,11 +14,13 @@ package scala.actors * The <code>CanReply</code> trait defines result-bearing message send operations. * * @author Philipp Haller + * + * @define actor `CanReply` */ trait CanReply[-T, +R] { /** - * Sends <code>msg</code> to this <code>CanReply</code> and + * Sends <code>msg</code> to this $actor and * awaits reply (synchronous). * * @param msg the message to be sent @@ -27,7 +29,7 @@ trait CanReply[-T, +R] { def !?(msg: T): R /** - * Sends <code>msg</code> to this <code>CanReply</code> and + * Sends <code>msg</code> to this $actor and * awaits reply (synchronous) within <code>msec</code> * milliseconds. * @@ -39,7 +41,7 @@ trait CanReply[-T, +R] { def !?(msec: Long, msg: T): Option[R] /** - * Sends <code>msg</code> to this <code>CanReply</code> and + * Sends <code>msg</code> to this $actor and * immediately returns a future representing the reply value. * * @param msg the message to be sent @@ -49,7 +51,7 @@ trait CanReply[-T, +R] { () => this !? msg /** - * Sends <code>msg</code> to this <code>CanReply</code> and + * Sends <code>msg</code> to this $actor and * immediately returns a future representing the reply value. * The reply is post-processed using the partial function * <code>handler</code>. This also allows to recover a more diff --git a/src/actors/scala/actors/Channel.scala b/src/actors/scala/actors/Channel.scala index 4c37de7665..e40a804e4a 100644 --- a/src/actors/scala/actors/Channel.scala +++ b/src/actors/scala/actors/Channel.scala @@ -35,45 +35,26 @@ case class ! [a](ch: Channel[a], msg: a) * <code>Channel</code> may receive from it. * * @author Philipp Haller + * + * @define actor channel + * @define channel channel */ -class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputChannel[Msg] { +class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputChannel[Msg] with CanReply[Msg, Any] { def this() = this(Actor.self) - /** - * Sends a message to this <code>Channel</code>. - * - * @param msg the message to be sent - */ def !(msg: Msg) { receiver ! scala.actors.!(this, msg) } - /** - * Sends a message to this <code>Channel</code> - * (asynchronous) supplying explicit reply destination. - * - * @param msg the message to send - * @param replyTo the reply destination - */ def send(msg: Msg, replyTo: OutputChannel[Any]) { receiver.send(scala.actors.!(this, msg), replyTo) } - /** - * Forwards <code>msg</code> to <code>this</code> keeping the - * last sender as sender instead of <code>self</code>. - */ def forward(msg: Msg) { receiver forward scala.actors.!(this, msg) } - /** - * Receives a message from this <code>Channel</code>. - * - * @param f a partial function with message patterns and actions - * @return result of processing the received value - */ def receive[R](f: PartialFunction[Msg, R]): R = { val C = this.asInstanceOf[Channel[Any]] val recvActor = receiver.asInstanceOf[Actor] @@ -82,21 +63,10 @@ class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputCha } } - /** - * Receives the next message from this <code>Channel</code>. - */ def ? : Msg = receive { case x => x } - /** - * Receives a message from this <code>Channel</code> within a certain - * time span. - * - * @param msec the time span before timeout - * @param f a partial function with message patterns and actions - * @return result of processing the received value - */ def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R = { val C = this.asInstanceOf[Channel[Any]] val recvActor = receiver.asInstanceOf[Actor] @@ -106,14 +76,6 @@ class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputCha } } - /** - * Receives a message from this <code>Channel</code>. - * <p> - * This method never returns. Therefore, the rest of the computation - * has to be contained in the actions of the partial function. - * - * @param f a partial function with message patterns and actions - */ def react(f: PartialFunction[Msg, Unit]): Nothing = { val C = this.asInstanceOf[Channel[Any]] receiver.react { @@ -121,16 +83,6 @@ class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputCha } } - /** - * Receives a message from this <code>Channel</code> within a certain - * time span. - * <p> - * This method never returns. Therefore, the rest of the computation - * has to be contained in the actions of the partial function. - * - * @param msec the time span before timeout - * @param f a partial function with message patterns and actions - */ def reactWithin(msec: Long)(f: PartialFunction[Any, Unit]): Nothing = { val C = this.asInstanceOf[Channel[Any]] val recvActor = receiver.asInstanceOf[Actor] @@ -140,13 +92,6 @@ class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputCha } } - /** - * Sends a message to this <code>Channel</code> and - * awaits reply. - * - * @param msg the message to be sent - * @return the reply - */ def !?(msg: Msg): Any = { val replyCh = new Channel[Any](Actor.self(receiver.scheduler)) receiver.send(scala.actors.!(this, msg), replyCh) @@ -155,15 +100,6 @@ class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputCha } } - /** - * Sends a message to this <code>Channel</code> and - * awaits reply within a certain time span. - * - * @param msec the time span before timeout - * @param msg the message to be sent - * @return <code>None</code> in case of timeout, otherwise - * <code>Some(x)</code> where <code>x</code> is the reply - */ def !?(msec: Long, msg: Msg): Option[Any] = { val replyCh = new Channel[Any](Actor.self(receiver.scheduler)) receiver.send(scala.actors.!(this, msg), replyCh) diff --git a/src/actors/scala/actors/Combinators.scala b/src/actors/scala/actors/Combinators.scala index 3c0be7ed15..6082f92323 100644 --- a/src/actors/scala/actors/Combinators.scala +++ b/src/actors/scala/actors/Combinators.scala @@ -12,28 +12,35 @@ package scala.actors private[actors] trait Combinators { + /** + * Enables the composition of suspendable closures using `andThen`, + * `loop`, `loopWhile`, etc. + */ implicit def mkBody[a](body: => a): Actor.Body[a] /** - * Causes <code>self</code> to repeatedly execute - * <code>body</code>. + * Repeatedly executes `body`. * - * @param body the code block to be executed + * @param body the block to be executed */ def loop(body: => Unit): Unit = body andThen loop(body) /** - * Causes <code>self</code> to repeatedly execute - * <code>body</code> while the condition - * <code>cond</code> is <code>true</code>. + * Repeatedly executes `body` while the condition `cond` is `true`. * * @param cond the condition to test - * @param body the code block to be executed + * @param body the block to be executed */ def loopWhile(cond: => Boolean)(body: => Unit): Unit = if (cond) { body andThen loopWhile(cond)(body) } else continue + /** + * Continues with the execution of the closure registered as + * continuation following `andThen`. Continues with the execution + * of the next loop iteration when invoked inside the body of `loop` + * or `loopWhile`. + */ def continue: Unit = throw new KillActorControl } diff --git a/src/actors/scala/actors/InputChannel.scala b/src/actors/scala/actors/InputChannel.scala index fa2fad43c6..dfe26b3462 100644 --- a/src/actors/scala/actors/InputChannel.scala +++ b/src/actors/scala/actors/InputChannel.scala @@ -15,11 +15,13 @@ package scala.actors * for all channels from which values can be received. * * @author Philipp Haller + * + * @define channel `InputChannel` */ trait InputChannel[+Msg] { /** - * Receives a message from this <code>InputChannel</code>. + * Receives a message from this $channel. * * @param f a partial function with message patterns and actions * @return result of processing the received value @@ -27,7 +29,7 @@ trait InputChannel[+Msg] { def receive[R](f: PartialFunction[Msg, R]): R /** - * Receives a message from this <code>InputChannel</code> within + * Receives a message from this $channel within * a certain time span. * * @param msec the time span before timeout @@ -37,8 +39,8 @@ trait InputChannel[+Msg] { def receiveWithin[R](msec: Long)(f: PartialFunction[Any, R]): R /** - * Receives a message from this <code>InputChannel</code>. - * <p> + * Receives a message from this $channel. + * * This method never returns. Therefore, the rest of the computation * has to be contained in the actions of the partial function. * @@ -47,9 +49,9 @@ trait InputChannel[+Msg] { def react(f: PartialFunction[Msg, Unit]): Nothing /** - * Receives a message from this <code>InputChannel</code> within + * Receives a message from this $channel within * a certain time span. - * <p> + * * This method never returns. Therefore, the rest of the computation * has to be contained in the actions of the partial function. * @@ -59,7 +61,7 @@ trait InputChannel[+Msg] { def reactWithin(msec: Long)(f: PartialFunction[Any, Unit]): Nothing /** - * Receives the next message from this <code>Channel</code>. + * Receives the next message from this $channel. */ def ? : Msg } diff --git a/src/actors/scala/actors/OutputChannel.scala b/src/actors/scala/actors/OutputChannel.scala index 514c445944..8bf92b448e 100644 --- a/src/actors/scala/actors/OutputChannel.scala +++ b/src/actors/scala/actors/OutputChannel.scala @@ -15,18 +15,18 @@ package scala.actors * for all channels to which values can be sent. * * @author Philipp Haller + * + * @define actor `OutputChannel` */ trait OutputChannel[-Msg] extends AbstractReactor[Msg] { /** - * Sends <code>msg</code> to this - * <code>OutputChannel</code> (asynchronous). + * Sends <code>msg</code> to this $actor (asynchronous). */ def !(msg: Msg): Unit /** - * Sends <code>msg</code> to this - * <code>OutputChannel</code> (asynchronous) supplying + * Sends <code>msg</code> to this $actor (asynchronous) supplying * explicit reply destination. * * @param msg the message to send @@ -35,14 +35,12 @@ trait OutputChannel[-Msg] extends AbstractReactor[Msg] { def send(msg: Msg, replyTo: OutputChannel[Any]): Unit /** - * Forwards <code>msg</code> to this - * <code>OutputChannel</code> (asynchronous). + * Forwards <code>msg</code> to this $actor (asynchronous). */ def forward(msg: Msg): Unit /** - * Returns the <code>Actor</code> that is - * receiving from this <code>OutputChannel</code>. + * Returns the <code>Actor</code> that is receiving from this $actor. */ def receiver: Actor } diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala index db43921056..a5bdcf1dd9 100644 --- a/src/actors/scala/actors/Reactor.scala +++ b/src/actors/scala/actors/Reactor.scala @@ -50,23 +50,25 @@ private[actors] object Reactor { * The Reactor trait provides lightweight actors. * * @author Philipp Haller + * + * @define actor reactor */ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { - /* The actor's mailbox. */ + /* The $actor's mailbox. */ private[actors] val mailbox = new MQueue[Msg]("Reactor") // guarded by this private[actors] val sendBuffer = new MQueue[Msg]("SendBuffer") - /* Whenever this actor executes on some thread, `waitingFor` is + /* Whenever this $actor executes on some thread, `waitingFor` is * guaranteed to be equal to `Reactor.waitingForNone`. * * In other words, whenever `waitingFor` is not equal to - * `Reactor.waitingForNone`, this actor is guaranteed not to execute + * `Reactor.waitingForNone`, this $actor is guaranteed not to execute * on some thread. * - * If the actor waits in a `react`, `waitingFor` holds the + * If the $actor waits in a `react`, `waitingFor` holds the * message handler that `react` was called with. * * guarded by this @@ -78,8 +80,7 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { private[actors] var _state: Actor.State.Value = Actor.State.New /** - * The behavior of a <code>Reactor</code> is specified by implementing - * this method. + * The $actor's behavior is specified by implementing this method. */ def act(): Unit @@ -92,13 +93,6 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { protected[actors] def mailboxSize: Int = mailbox.size - /** - * Sends <code>msg</code> to this actor (asynchronous) supplying - * explicit reply destination. - * - * @param msg the message to send - * @param replyTo the reply destination - */ def send(msg: Msg, replyTo: OutputChannel[Any]) { val todo = synchronized { if (waitingFor ne Reactor.waitingForNone) { @@ -194,8 +188,8 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { } /** - * Receives a message from this actor's mailbox. - * <p> + * Receives a message from this $actor's mailbox. + * * This method never returns. Therefore, the rest of the computation * has to be contained in the actions of the partial function. * @@ -208,7 +202,7 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { } /* This method is guaranteed to be executed from inside - * an actors act method. + * an $actor's act method. * * assume handler != null * @@ -218,6 +212,9 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { scheduler executeFromActor makeReaction(null, handler, msg) } + /** + * Starts this $actor. + */ def start(): Reactor[Msg] = synchronized { if (_state == Actor.State.New) { _state = Actor.State.Runnable @@ -228,7 +225,7 @@ trait Reactor[Msg >: Null] extends OutputChannel[Msg] with Combinators { this } - /** Returns the execution state of this actor. + /** Returns the execution state of this $actor. * * @return the execution state */ diff --git a/src/actors/scala/actors/ReactorCanReply.scala b/src/actors/scala/actors/ReactorCanReply.scala index c53e3a78e1..9002a55b87 100644 --- a/src/actors/scala/actors/ReactorCanReply.scala +++ b/src/actors/scala/actors/ReactorCanReply.scala @@ -19,25 +19,9 @@ package scala.actors private[actors] trait ReactorCanReply extends CanReply[Any, Any] { _: ReplyReactor => - /** - * Sends <code>msg</code> to this actor and awaits reply - * (synchronous). - * - * @param msg the message to be sent - * @return the reply - */ def !?(msg: Any): Any = (this !! msg)() - /** - * Sends <code>msg</code> to this actor and awaits reply - * (synchronous) within <code>msec</code> milliseconds. - * - * @param msec the time span before timeout - * @param msg the message to be sent - * @return <code>None</code> in case of timeout, otherwise - * <code>Some(x)</code> where <code>x</code> is the reply - */ def !?(msec: Long, msg: Any): Option[Any] = { val myself = Actor.rawSelf(this.scheduler) val res = new scala.concurrent.SyncVar[Any] @@ -55,20 +39,9 @@ private[actors] trait ReactorCanReply extends CanReply[Any, Any] { res.get(msec) } - /** - * Sends <code>msg</code> to this actor and immediately - * returns a future representing the reply value. - */ override def !!(msg: Any): Future[Any] = this !! (msg, { case x => x }) - /** - * Sends <code>msg</code> to this actor and immediately - * returns a future representing the reply value. - * The reply is post-processed using the partial function - * <code>handler</code>. This also allows to recover a more - * precise type for the reply value. - */ override def !![A](msg: Any, handler: PartialFunction[Any, A]): Future[A] = { val myself = Actor.rawSelf(this.scheduler) val ftch = new ReactChannel[A](myself) diff --git a/src/actors/scala/actors/ReplyReactor.scala b/src/actors/scala/actors/ReplyReactor.scala index 26057ab9cb..665ed3091f 100644 --- a/src/actors/scala/actors/ReplyReactor.scala +++ b/src/actors/scala/actors/ReplyReactor.scala @@ -20,6 +20,8 @@ import java.util.{Timer, TimerTask} * </p> * * @author Philipp Haller + * + * @define actor `ReplyReactor` */ trait ReplyReactor extends Reactor[Any] with ReactorCanReply { @@ -38,7 +40,7 @@ trait ReplyReactor extends Reactor[Any] with ReactorCanReply { private[actors] var onTimeout: Option[TimerTask] = None /** - * Returns the actor which sent the last received message. + * Returns the $actor which sent the last received message. */ protected[actors] def sender: OutputChannel[Any] = senders.head @@ -49,16 +51,10 @@ trait ReplyReactor extends Reactor[Any] with ReactorCanReply { sender ! msg } - /** - * Sends <code>msg</code> to this actor (asynchronous). - */ override def !(msg: Any) { send(msg, Actor.rawSelf(scheduler)) } - /** - * Forwards <code>msg</code> to this actor (asynchronous). - */ override def forward(msg: Any) { send(msg, Actor.sender) } @@ -115,9 +111,9 @@ trait ReplyReactor extends Reactor[Any] with ReactorCanReply { } /** - * Receives a message from this actor's mailbox within a certain + * Receives a message from this $actor's mailbox within a certain * time span. - * <p> + * * This method never returns. Therefore, the rest of the computation * has to be contained in the actions of the partial function. * diff --git a/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala b/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala index ab4fca04ca..4aaef16661 100644 --- a/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala +++ b/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala @@ -3,7 +3,6 @@ package scheduler import java.util.{Collection, ArrayList} import scala.concurrent.forkjoin._ -import scala.util.Random /** The <code>ForkJoinScheduler</code> is backed by a lightweight * fork-join task execution framework. @@ -23,12 +22,19 @@ class ForkJoinScheduler(val initCoreSize: Int, val maxSize: Int, daemon: Boolean protected val CHECK_FREQ = 10 + // this random number generator is only used in fair mode + private lazy val random = new java.util.Random // guarded by random + + def this(d: Boolean, f: Boolean) { + this(ThreadPoolConfig.corePoolSize, ThreadPoolConfig.maxPoolSize, d, f) + } + def this(d: Boolean) { - this(ThreadPoolConfig.corePoolSize, ThreadPoolConfig.maxPoolSize, d, true) + this(d, true) // default is fair } def this() { - this(false) + this(false) // default is non-daemon } private def makeNewPool(): DrainableForkJoinPool = { @@ -109,7 +115,7 @@ class ForkJoinScheduler(val initCoreSize: Int, val maxSize: Int, daemon: Boolean override def executeFromActor(task: Runnable) { // in fair mode: 2% chance of submitting to global task queue - if (fair && Random.nextInt(50) == 1) + if (fair && random.synchronized { random.nextInt(50) == 1 }) pool.execute(task) else task.asInstanceOf[RecursiveAction].fork() diff --git a/src/build/pack.xml b/src/build/pack.xml index 5c5c8fbd8d..fa6c4ade20 100644 --- a/src/build/pack.xml +++ b/src/build/pack.xml @@ -102,6 +102,8 @@ MAIN DISTRIBUTION SBAZ dir="${dist.dir}/bin" includes="scala,scala.bat,scalac,scalac.bat,scaladoc,scaladoc.bat,fsc,fsc.bat"/> <libset dir="${dist.dir}/lib" includes="scala-compiler.jar,jline.jar"/> + <miscset dir="${dist.dir}/misc/scala-devel" + includes="plugins/continuations.jar"/> <manset dir="${dist.dir}/man" includes="**"/> <srcset dir="${dist.dir}/src" includes="scala-compiler-src.jar"/> </sbaz> @@ -200,7 +202,7 @@ MAIN DISTRIBUTION SBAZ <sequential> <mkdir dir="${dists.dir}/maven/${version.number}/plugins/@{mvn.artifact.name}"/> <copy todir="${dists.dir}/maven/${version.number}/plugins/@{mvn.artifact.name}"> - <fileset dir="${dist.dir}/plugins/"> + <fileset dir="${dist.dir}/misc/scala-devel/plugins/"> <filename name="@{mvn.artifact.name}.jar"/> </fileset> <fileset dir="${src.dir}/build/maven/"> diff --git a/src/compiler/scala/tools/cmd/CommandLine.scala b/src/compiler/scala/tools/cmd/CommandLine.scala new file mode 100644 index 0000000000..8cb4c00b14 --- /dev/null +++ b/src/compiler/scala/tools/cmd/CommandLine.scala @@ -0,0 +1,107 @@ +/* NEST (New Scala Test) + * Copyright 2007-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +import scala.collection.mutable.ListBuffer + +/** An instance of a command line, parsed according to a Spec. + */ +class CommandLine(val spec: Reference, val originalArgs: List[String]) { + def this(spec: Reference, line: String) = this(spec, Parser tokenize line) + def this(spec: Reference, args: Array[String]) = this(spec, args.toList) + + import spec.{ isAnyOption, isUnaryOption, isBinaryOption, isExpandOption } + + def assumeBinary = true + def enforceArity = true + def onlyKnownOptions = false + + val Terminator = "--" + val ValueForUnaryOption = "true" // so if --opt is given, x(--opt) = true + + def mapForUnary(opt: String) = Map(opt -> ValueForUnaryOption) + def errorFn(msg: String) = println(msg) + + /** argMap is option -> argument (or "" if it is a unary argument) + * residualArgs are what is left after removing the options and their args. + */ + lazy val (argMap, residualArgs) = { + val residualBuffer = new ListBuffer[String] + + def isOption(s: String) = isAnyOption(s) || ((s startsWith "-") && !onlyKnownOptions) + + def unknownOption(opt: String) = + errorFn("Option '%s' not recognized.".format(opt)) + def missingArg(opt: String, what: String) = + errorFn("Option '%s' requires argument, found %s instead.".format(opt, what)) + + def loop(args: List[String]): Map[String, String] = { + def residual(xs: List[String]) = { residualBuffer ++= xs ; Map[String, String]() } + + /** Returns Some(List(args)) if this option expands to an + * argument list and it's not returning only the same arg. + */ + def expand(s1: String) = { + if (isExpandOption(s1)) { + val s2 = spec expandArg s1 + if (s2 == List(s1)) None + else Some(s2) + } + else None + } + + args match { + case Nil => Map() + case Terminator :: xs => residual(xs) + case x :: Nil => + expand(x) foreach (exp => return loop(exp)) + if (isBinaryOption(x) && enforceArity) + missingArg(x, "EOF") + + if (isUnaryOption(x)) mapForUnary(x) + else residual(args) + case x1 :: x2 :: xs => + expand(x1) foreach (exp => return loop(exp ++ args.tail)) + + if (x2 == Terminator) mapForUnary(x1) ++ residual(xs) + else if (isUnaryOption(x1)) mapForUnary(x1) ++ loop(args.tail) + else if (isBinaryOption(x1)) Map(x1 -> x2) ++ loop(xs) + else residual(List(x1)) ++ loop(args.tail) + } + } + + (loop(originalArgs), residualBuffer map stripQuotes toList) + } + + def apply(arg: String) = argMap(arg) + def get(arg: String) = argMap get arg + def isSet(arg: String) = argMap contains arg + + def getOrElse(arg: String, orElse: => String) = if (isSet(arg)) apply(arg) else orElse + + override def toString() = argMap.toString + " " + residualArgs.toString +} + +object CommandLine { + def apply(args: List[String], unary: List[String], binary: List[String]) = { + /** XXX Temporarily assembling a fake spec so we can continue to + * do ad-hoc parsing based on a list of unary and binary args. + * Should either clean this up or do it differently. + */ + object NoSpec extends Reference { + unary foreach (_ --? ) + binary foreach (_ --| ) + + protected def creator(args: List[String]) = error("No Spec") + def programInfo = Spec.Names("", "") + lazy val referenceSpec = this + } + + new CommandLine(NoSpec, args) + } +} + diff --git a/src/compiler/scala/tools/cmd/Demo.scala b/src/compiler/scala/tools/cmd/Demo.scala new file mode 100644 index 0000000000..7014e6b4d7 --- /dev/null +++ b/src/compiler/scala/tools/cmd/Demo.scala @@ -0,0 +1,85 @@ +/* NEST (New Scala Test) + * Copyright 2007-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +/** A sample command specification for illustrative purposes. + * First take advantage of the meta-options: + * + * // this command creates an executable runner script "demo" + * % scala scala.tools.cmd.Demo --generate-runner demo + * + * // this one creates and sources a completion file - note backticks + * % `./demo --bash` + * + * // and now you have a runner with working completion + * % ./demo --<tab> + * --action --defint --int + * --bash --defstr --str + * --defenv --generate-runner --unary + * + * The normal option configuration is plausibly self-explanatory. + */ +trait DemoSpec extends Spec with Meta.StdOpts with Interpolation { + lazy val referenceSpec = DemoSpec + lazy val programInfo = Spec.Names("demo", "scala.tools.cmd.Demo") + + help("""Usage: demo [<options>]""") + heading("Unary options:") + + val optIsUnary = "unary" / "a unary option" --? ; + ("action" / "a body which may be run") --> println("Hello, I am the --action body.") + + heading("Binary options:") + val optopt = "str" / "an optional String" --| + val optoptInt = ("int" / "an optional Int") . --^[Int] + val optEnv = "defenv" / "an optional String" defaultToEnv "PATH" + val optDefault = "defstr" / "an optional String" defaultTo "default" + val optDefaultInt = "defint" / "an optional Int" defaultTo -1 + val optExpand = "alias" / "an option which expands" expandTo ("--int", "15") +} + +object DemoSpec extends DemoSpec with Property { + lazy val propMapper = new PropertyMapper(DemoSpec) + + type ThisCommandLine = SpecCommandLine + def creator(args: List[String]) = + new SpecCommandLine(args) { + override def onlyKnownOptions = true + override def errorFn(msg: String) = { println("Error: " + msg) ; System.exit(0) } + } +} + +class Demo(args: List[String]) extends { + val parsed = DemoSpec(args: _*) +} with DemoSpec with Instance { + import java.lang.reflect._ + + def helpMsg = DemoSpec.helpMsg + def demoSpecMethods = this.getClass.getMethods.toList + private def isDemo(m: Method) = (m.getName startsWith "opt") && !(m.getName contains "$") && (m.getParameterTypes.isEmpty) + + def demoString(ms: List[Method]) = { + val longest = ms map (_.getName.length) max + val formatStr = " %-" + longest + "s: %s" + val xs = ms map (m => formatStr.format(m.getName, m.invoke(this))) + + xs mkString ("Demo(\n ", "\n ", "\n)\n") + } + + override def toString = demoString(demoSpecMethods filter isDemo) +} + +object Demo { + def main(args: Array[String]): Unit = { + val runner = new Demo(args.toList) + + if (args.isEmpty) + println(runner.helpMsg) + + println(runner) + } +} diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala new file mode 100644 index 0000000000..81454e7a30 --- /dev/null +++ b/src/compiler/scala/tools/cmd/FromString.scala @@ -0,0 +1,72 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +import nsc.io.{ Path, File, Directory } +import reflect.OptManifest + +/** A general mechanism for defining how a command line argument + * (always a String) is transformed into an arbitrary type. A few + * example instances are in the companion object, but in general + * either IntFromString will suffice or you'll want custom transformers. + */ +abstract class FromString[+T](implicit m: OptManifest[T]) extends PartialFunction[String, T] { + def apply(s: String): T + def isDefinedAt(s: String): Boolean = true + def zero: T = apply("") + + def targetString: String = m.toString +} + +object FromString { + // We need these because we clash with the String => Path implicits. + private def toFile(s: String) = new File(new java.io.File(s)) + private def toDir(s: String) = new Directory(new java.io.File(s)) + + /** Path related stringifiers. + */ + val ExistingFile: FromString[File] = new FromString[File] { + override def isDefinedAt(s: String) = toFile(s).isFile + def apply(s: String): File = + if (isDefinedAt(s)) toFile(s) + else cmd.runAndExit(println("'%s' is not an existing file." format s)) + } + val ExistingDir: FromString[Directory] = new FromString[Directory] { + override def isDefinedAt(s: String) = toDir(s).isDirectory + def apply(s: String): Directory = + if (isDefinedAt(s)) toDir(s) + else cmd.runAndExit(println("'%s' is not an existing directory." format s)) + } + def ExistingDirRelativeTo(root: Directory) = new FromString[Directory] { + private def resolve(s: String) = toDir(s) toAbsoluteWithRoot root toDirectory + override def isDefinedAt(s: String) = resolve(s).isDirectory + def apply(s: String): Directory = + if (isDefinedAt(s)) resolve(s) + else cmd.runAndExit(println("'%s' is not an existing directory." format resolve(s))) + } + + /** Argument expander, i.e. turns single argument "foo bar baz" into argument + * list "foo", "bar", "baz". + */ + val ArgumentsFromString: FromString[List[String]] = new FromString[List[String]] { + def apply(s: String) = toArgs(s) + } + + /** Identity. + */ + implicit val StringFromString: FromString[String] = new FromString[String] { + def apply(s: String): String = s + } + + /** Implicit as the most likely to be useful as-is. + */ + implicit val IntFromString: FromString[Int] = new FromString[Int] { + override def isDefinedAt(s: String) = safeToInt(s).isDefined + def apply(s: String) = safeToInt(s).get + def safeToInt(s: String): Option[Int] = try Some(java.lang.Integer.parseInt(s)) catch { case _: NumberFormatException => None } + } +} diff --git a/src/compiler/scala/tools/cmd/Instance.scala b/src/compiler/scala/tools/cmd/Instance.scala new file mode 100644 index 0000000000..4d319b98cc --- /dev/null +++ b/src/compiler/scala/tools/cmd/Instance.scala @@ -0,0 +1,23 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +/** The trait mixed into each instance of a specification. + * + * @see Reference + */ +trait Instance extends Spec { + def parsed: CommandLine + + protected def help(str: => String): Unit = () + + def isSet(s: String) = parsed isSet toOpt(s) + def originalArgs = parsed.originalArgs + + type OptionMagic = Opt.Instance + protected implicit def optionMagicAdditions(name: String) = new Opt.Instance(programInfo, parsed, name) +} diff --git a/src/compiler/scala/tools/cmd/Interpolation.scala b/src/compiler/scala/tools/cmd/Interpolation.scala new file mode 100644 index 0000000000..6b86a35bb9 --- /dev/null +++ b/src/compiler/scala/tools/cmd/Interpolation.scala @@ -0,0 +1,59 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +/** Interpolation logic for generated files. The idea is to be + * able to write in terms of @@THIS@@ and @@THAT@@ and the reference + * specification knows enough to perform the substitutions. Warrants + * expansion. + */ +trait Interpolation { + self: Spec => + + private lazy val reference = referenceSpec + import reference._ + + object interpolate { + def mapper: Map[String, () => String] = Map( + "PROGRAM" -> (() => programInfo.runner), + "ALLOPTIONS" -> (() => options.all mkString " "), + "MAINCLASS" -> (() => programInfo.mainClass) + ) + + private def mark(key: String) = "@@" + key + "@@" + def apply(template: String) = mapper.foldLeft(template) { case (s, (key, f)) => s.replaceAll(mark(key), f()) } + } +} + +object Interpolation { + /** A simple template for generating bash completion functions. + */ + lazy val bashTemplate = """ + |_@@PROGRAM@@() + |{ + | local cur opts base + | COMPREPLY=() + | cur="${COMP_WORDS[COMP_CWORD]}" + | opts="@@ALLOPTIONS@@" + | + | COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + | _filedir + | return 0 + |} && complete -F _@@PROGRAM@@ @@PROGRAM@@ + """.stripMargin + + /** A simple template for generating a runner script. + */ + val runnerTemplate = """ + |#!/bin/sh + |# + | + |scala @@MAINCLASS@@ $* + | + """.stripMargin +} + diff --git a/src/compiler/scala/tools/cmd/Meta.scala b/src/compiler/scala/tools/cmd/Meta.scala new file mode 100644 index 0000000000..5a09766b13 --- /dev/null +++ b/src/compiler/scala/tools/cmd/Meta.scala @@ -0,0 +1,62 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +import nsc.io.File +import Interpolation._ + +/** Meta-options for command line tools. We could have all kinds + * of additional goodness here, but for now it's completion and script + * generation. See Demo for example usage. + */ +object Meta { + trait Opt { + def name: String + def action: () => Unit + } + + trait StdOpts { + self: Spec with Interpolation => + + Bash.name --> runAndExit(Bash.action()) + val runnerFileName = Runner.name --| ; + + if (runnerFileName.isDefined) + runAndExit(Runner.action()) + + /** I think we're as close as we can get to bundling completion with + * the program given the constraints imposed by bash. This outputs + * the completion function to a tempfile and echoes ". /path/to/file" + * to the console. Place it inside backtickes like `partest --bash` + * and voila, you have absorbed command completion. + */ + object Bash extends Opt { + val name = "bash" + val action = () => { + val file = File.makeTemp("scala.cmd.bash") + file writeAll interpolate(bashTemplate) + + // Would be nice to print something like this but comments are + // not always comments in bash, and breaking it is worse. + // Console println ("# Run the following line, or issue the --bash command in `backticks`.") + Console println (". " + file.normalize.path) + } + } + + /** A very basic runner script. + */ + object Runner extends Opt { + val name = "generate-runner" + val action = () => { + val file = File(runnerFileName.get) + file writeAll interpolate(runnerTemplate) + file setExecutable true + () + } + } + } +} diff --git a/src/compiler/scala/tools/cmd/Opt.scala b/src/compiler/scala/tools/cmd/Opt.scala new file mode 100644 index 0000000000..9e3c324deb --- /dev/null +++ b/src/compiler/scala/tools/cmd/Opt.scala @@ -0,0 +1,91 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +import nsc.Properties.envOrElse +import Spec.Names + +/** Machinery for what amounts to a command line specification DSL. + * It is designed so the same specification trait can be used for + * two different purposes: generating a singleton specification object + * (trait Reference) and providing well typed vals for every configurable + * option in response to any given set of arguments (trait Instance). + */ +object Opt { + trait Error { + self: Implicit => + + protected def fail(msg: String) = runAndExit(println(programInfo.runner + ": " + msg)) + protected def failOption(arg: String, why: String) = fail("%s: '%s' is %s".format(opt, arg, why)) + } + + trait Implicit { + def name: String + def programInfo: Names + protected def opt = toOpt(name) + + def --? : Boolean // --opt is set + def --> (body: => Unit): Unit // if --opt is set, execute body + def --| : Option[String] // --opt <arg: String> is optional, result is Option[String] + def --^[T: FromString] : Option[T] // --opt <arg: T> is optional, result is Option[T] + + def optMap[T](f: String => T) = --| map f + + /** Names. + */ + def defaultTo[T: FromString](default: T): T + def defaultToEnv(envVar: String): String + def choiceOf[T: FromString](choices: T*): Option[T] + def expandTo(args: String*): Unit + + /** Help. + */ + def /(descr: String): String // --opt has help description 'descr' + } + + class Reference(val programInfo: Names, val options: Reference.Accumulators, val name: String) extends Implicit { + import options._ + + def --? = { addUnary(opt) ; false } + def --> (body: => Unit) = { addUnary(opt) } + def --| = { addBinary(opt) ; None } + def --^[T: FromString] = { addBinary(opt) ; None } + + def defaultTo[T: FromString](default: T) = { addBinary(opt) ; addHelpDefault(() => default.toString) ; default } + def defaultToEnv(envVar: String) = { addBinary(opt) ; addHelpEnvDefault(envVar) ; "" } + def choiceOf[T: FromString](choices: T*) = { addBinary(opt) ; None } + def expandTo(args: String*) = { addExpand(name, args.toList) ; addHelpAlias(() => args mkString " ") } + + def /(descr: String) = returning(name)(_ => addHelp(() => helpFormatStr.format(opt, descr))) + } + + class Instance(val programInfo: Names, val parsed: CommandLine, val name: String) extends Implicit with Error { + def --? = parsed isSet opt + def --> (body: => Unit) = if (parsed isSet opt) body + def --| = parsed get opt + def --^[T: FromString] = { + val fs = implicitly[FromString[T]] + --| map { arg => + if (fs isDefinedAt arg) fs(arg) + else failOption(arg, "not a " + fs.targetString) + } + } + + def defaultTo[T: FromString](default: T) = --^[T] getOrElse default + def defaultToEnv(envVar: String) = --| getOrElse envOrElse(envVar, "") + def expandTo(args: String*) = () + + def choiceOf[T: FromString](choices: T*) = { + --^[T] map { arg => + if (choices contains arg) arg + else failOption(arg.toString, "not a valid choice from " + choices) + } + } + + def /(descr: String) = name + } +} diff --git a/src/compiler/scala/tools/cmd/Parser.scala b/src/compiler/scala/tools/cmd/Parser.scala new file mode 100644 index 0000000000..f4bce745e2 --- /dev/null +++ b/src/compiler/scala/tools/cmd/Parser.scala @@ -0,0 +1,52 @@ +/* NEST (New Scala Test) + * Copyright 2007-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +import scala.util.parsing.combinator._ +import scala.util.parsing.input.CharArrayReader.EofCh + +/** A simple (overly so) command line parser. + * !!! This needs a thorough test suite to make sure quoting is + * done correctly and portably. + */ +trait ParserUtil extends Parsers { + class ParserPlus[+T](underlying: Parser[T]) { + def !~>[U](p: => Parser[U]): Parser[U] = (underlying ~! p) ^^ { case a~b => b } + def <~![U](p: => Parser[U]): Parser[T] = (underlying ~! p) ^^ { case a~b => a } + } + protected implicit def parser2parserPlus[T](p: Parser[T]): ParserPlus[T] = new ParserPlus(p) +} + +object Parser extends RegexParsers with ParserUtil { + override def skipWhitespace = false + + def elemExcept(xs: Elem*): Parser[Elem] = elem("elemExcept", x => x != EofCh && !(xs contains x)) + def elemOf(xs: Elem*): Parser[Elem] = elem("elemOf", xs contains _) + def escaped(ch: Char): Parser[String] = "\\" + ch + def mkQuoted(ch: Char): Parser[String] = ( + elem(ch) !~> rep(escaped(ch) | elemExcept(ch)) <~ ch ^^ (_.mkString) + | failure("Unmatched %s in input." format ch) + ) + + /** Apparently windows can't deal with the quotes sticking around. */ + lazy val squoted: Parser[String] = mkQuoted('\'') // ^^ (x => "'%s'" format x) + lazy val dquoted: Parser[String] = mkQuoted('"') // ^^ (x => "\"" + x + "\"") + lazy val token: Parser[String] = """\S+""".r + + lazy val argument: Parser[String] = squoted | dquoted | token + lazy val commandLine: Parser[List[String]] = phrase(repsep(argument, whiteSpace)) + + class ParseException(msg: String) extends RuntimeException(msg) + + def tokenize(line: String): List[String] = tokenize(line, x => throw new ParseException(x)) + def tokenize(line: String, errorFn: String => Unit): List[String] = { + parse(commandLine, line.trim) match { + case Success(args, _) => args + case NoSuccess(msg, rest) => errorFn(msg) ; Nil + } + } +} diff --git a/src/compiler/scala/tools/cmd/Property.scala b/src/compiler/scala/tools/cmd/Property.scala new file mode 100644 index 0000000000..009e7e6142 --- /dev/null +++ b/src/compiler/scala/tools/cmd/Property.scala @@ -0,0 +1,71 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +import nsc.io._ +import java.util.Properties +import java.io.FileInputStream + +/** Contains logic for translating a property key/value pair into + * equivalent command line arguments. The default settings will + * translate, given programInfo.runner == "foo" : + * + * foo.bar=true to --bar // if --bar is unary + * foo.bar=quux to --bar quux // if --bar is binary + */ +class PropertyMapper(reference: Reference) extends (((String, String)) => List[String]) { + import reference._ + lazy val RunnerName = programInfo.runner + + // e.g. "partest.shootout" -> "--shootout" + def propNameToOptionName(key: String): Option[String] = (key split '.').toList match { + case List(RunnerName, name) => Some(name) + case _ => None + } + + def isPassThrough(key: String): Boolean = false // e.g. "partest.options" + def onError(key: String, value: String): Unit = () // called when translate fails + + def translate(key: String, value: String): List[String] = { + val opt = toOpt(key) + + if (isUnaryOption(key) && isTrue(value)) List(opt) + else if (isBinaryOption(key)) List(opt, value) + else returning(Nil)(_ => onError(key, value)) + } + def isTrue(value: String) = List("yes", "on", "true") contains value.toLowerCase + + def apply(kv: (String, String)): List[String] = { + val (k, v) = kv + + if (isPassThrough(k)) toArgs(v) + else propNameToOptionName(k) match { + case Some(optName) => translate(optName, v) + case _ => Nil + } + } +} + +trait Property extends Reference { + def propMapper: PropertyMapper + override def propertyArgs: List[String] = systemPropertiesToOptions + + def loadProperties(file: File): Properties = + returning(new Properties)(_ load new FileInputStream(file.path)) + + def systemPropertiesToOptions: List[String] = + propertiesToOptions(System.getProperties) + + def propertiesToOptions(file: File): List[String] = + propertiesToOptions(loadProperties(file)) + + def propertiesToOptions(props: java.util.Properties): List[String] = { + import collection.JavaConversions._ + propertiesToOptions(props.toList) + } + def propertiesToOptions(props: List[(String, String)]) = props flatMap propMapper +} diff --git a/src/compiler/scala/tools/cmd/Reference.scala b/src/compiler/scala/tools/cmd/Reference.scala new file mode 100644 index 0000000000..695868191b --- /dev/null +++ b/src/compiler/scala/tools/cmd/Reference.scala @@ -0,0 +1,98 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +import collection.mutable.ListBuffer +import nsc.Properties.envOrNone + +/** Mixes in the specification trait and uses the vals therein to + * side-effect private accumulators. From this emerges formatted help, + * lists of unary and binary arguments, an apply which can creates + * instances of the specification, and etc. + * + * @see Instance + */ +trait Reference extends Spec { + lazy val options = new Reference.Accumulators() + import options._ + + def helpMsg = options.helpMsg + def propertyArgs: List[String] = Nil + + def isUnaryOption(s: String) = unary contains toOpt(s) + def isBinaryOption(s: String) = binary contains toOpt(s) + def isExpandOption(s: String) = expansionMap contains toOpt(s) + def isAnyOption(s: String) = isUnaryOption(s) || isBinaryOption(s) || isExpandOption(s) + + def expandArg(arg: String) = expansionMap.getOrElse(fromOpt(arg), List(arg)) + + protected def help(str: => String) = addHelp(() => str) + + type ThisCommandLine <: SpecCommandLine + class SpecCommandLine(args: List[String]) extends CommandLine(Reference.this, args) { } + protected def creator(args: List[String]): ThisCommandLine + final def apply(args: String*): ThisCommandLine = creator(propertyArgs ++ args flatMap expandArg) + + type OptionMagic = Opt.Reference + protected implicit def optionMagicAdditions(name: String) = new Opt.Reference(programInfo, options, name) +} + +object Reference { + val MaxLine = 80 + + class Accumulators() { + private var _help = new ListBuffer[() => String] + private var _unary = List[String]() + private var _binary = List[String]() + private var _expand = Map[String, List[String]]() + + def helpFormatStr = " %-" + longestArg + "s %s" + def defaultFormatStr = (" " * (longestArg + 7)) + "%s" + + def addUnary(s: String) = _unary +:= s + def addBinary(s: String) = _binary +:= s + + def addExpand(opt: String, expanded: List[String]) = + _expand += (opt -> expanded) + + def mapHelp(g: String => String) = { + val idx = _help.length - 1 + val f = _help(idx) + + _help(idx) = () => g(f()) + } + + def addHelp(f: () => String) = _help += f + def addHelpAlias(f: () => String) = mapHelp { s => + val str = "alias for '%s'" format f() + def noHelp = (helpFormatStr.format("", "")).length == s.length + val str2 = if (noHelp) str else " (" + str + ")" + + s + str2 + } + def addHelpDefault(f: () => String) = mapHelp { s => + val str = "(default: %s)" format f() + + if (s.length + str.length < MaxLine) s + " " + str + else defaultFormatStr.format(s, str) + } + def addHelpEnvDefault(name: String) = mapHelp { s => + val line1 = "%s (default: %s)".format(s, name) + val envNow = envOrNone(name) map ("'" + _ + "'") getOrElse "unset" + val line2 = defaultFormatStr.format("Currently " + envNow) + + line1 + "\n" + line2 + } + + lazy val unary = (_unary ++ _expand.keys).distinct + lazy val binary = _binary.distinct + lazy val all = unary ++ binary + lazy val expansionMap = _expand + lazy val helpMsg = _help map (f => f() + "\n") mkString + lazy val longestArg = all map (_.length) max + } +} diff --git a/src/compiler/scala/tools/cmd/Spec.scala b/src/compiler/scala/tools/cmd/Spec.scala new file mode 100644 index 0000000000..c8283165d9 --- /dev/null +++ b/src/compiler/scala/tools/cmd/Spec.scala @@ -0,0 +1,45 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd + +/** This trait works together with others in scala.tools.cmd to allow + * declaratively specifying a command line program, with many attendant + * benefits. See scala.tools.cmd.DemoSpec for an example. + */ +trait Spec { + def referenceSpec: Reference + def programInfo: Spec.Names + + protected def help(str: => String): Unit + protected def heading(str: => String): Unit = help("\n " + str) + + type OptionMagic <: Opt.Implicit + protected implicit def optionMagicAdditions(s: String): OptionMagic +} + +object Spec { + case class Names(runner: String, mainClass: String) { } + + class Accumulator[T: FromString]() { + private var _buf: List[T] = Nil + + def convert(s: String) = implicitly[FromString[T]] apply s + def apply(s: String): T = returning(convert(s))(_buf +:= _) + + lazy val get = _buf + } + + class Choices[T: FromString](val xs: List[T]) { + def fs: FromString[T] = implicitly[FromString[T]] + def contains(x: T) = xs contains x + override def toString = xs.mkString("{ ", ", ", " }") + } + + class EnvironmentVar(val name: String) { + override def toString = "${%s}" format name + } +} diff --git a/src/compiler/scala/tools/cmd/package.scala b/src/compiler/scala/tools/cmd/package.scala new file mode 100644 index 0000000000..33d3892077 --- /dev/null +++ b/src/compiler/scala/tools/cmd/package.scala @@ -0,0 +1,28 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools + +package object cmd { + def returning[T](x: T)(f: T => Unit): T = { f(x) ; x } + + private[cmd] def debug(msg: String) = println(msg) + + def runAndExit(body: => Unit): Nothing = { + body + System exit 0 + error("unreachable") + } + + def toOpt(s: String) = if (s startsWith "--") s else "--" + s + def fromOpt(s: String) = s stripPrefix "--" + def toArgs(line: String) = Parser tokenize line + def fromArgs(args: List[String]) = args mkString " " + + def stripQuotes(s: String) = { + def isQuotedBy(c: Char) = s.length > 0 && s.head == c && s.last == c + if (List('"', '\'') exists isQuotedBy) s.tail.init else s + } +} diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 15da6f6fec..3e54b68daf 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -512,7 +512,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable phasesSet += uncurry // uncurry, translate function values to anonymous classes phasesSet += tailCalls // replace tail calls by jumps - if (settings.specialize.value) + if (!settings.nospecialization.value) phasesSet += specializeTypes phasesSet += explicitOuter // replace C.this by explicit outer pointers, eliminate pattern matching phasesSet += erasure // erase types, add interfaces for traits diff --git a/src/compiler/scala/tools/nsc/Phase.scala b/src/compiler/scala/tools/nsc/Phase.scala index de089ff7b6..cd5a399c12 100644 --- a/src/compiler/scala/tools/nsc/Phase.scala +++ b/src/compiler/scala/tools/nsc/Phase.scala @@ -36,7 +36,7 @@ abstract class Phase(val prev: Phase) { def devirtualized: Boolean = false def erasedTypes: Boolean = false def flatClasses: Boolean = false - def keepsTypeParams = false + def keepsTypeParams = true def run: Unit override def toString() = name diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 3144d8140d..febb4b221d 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -58,13 +58,17 @@ trait DocComments { self: SymbolTable => * of the same string are done, which is * interpreted as a recursive variable definition. */ - def expandedDocComment(sym: Symbol, site: Symbol): String = - expandVariables(cookedDocComment(sym), sym, site) + def expandedDocComment(sym: Symbol, site: Symbol): String = { + // when parsing a top level class or module, use the (module-)class itself to look up variable definitions + val site1 = if ((sym.isModule || sym.isClass) && (site hasFlag Flags.PACKAGE)) sym + else site + expandVariables(cookedDocComment(sym), sym, site1) + } /** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing. * @param sym The symbol for which doc comment is returned (site is always the containing class) */ - def expandedDocComment(sym: Symbol): String = expandedDocComment(sym, sym) + def expandedDocComment(sym: Symbol): String = expandedDocComment(sym, sym.enclClass) /** The list of use cases of doc comment of symbol `sym` seen as a member of class * `site`. Each use case consists of a synthetic symbol (which is entered nowhere else), @@ -203,11 +207,18 @@ trait DocComments { self: SymbolTable => def lookupVariable(vble: String, site: Symbol): Option[String] = if (site == NoSymbol) None - else - mapFind(site.info.baseClasses)(defs(_).get(vble)) match { + else { + def lookInBaseClasses = mapFind(site.info.baseClasses)(defs(_).get(vble)) match { case None => lookupVariable(vble, site.owner) case someStr => someStr } + if (site.isModule) + defs(site).get(vble) match { + case Some(str) => return Some(str) + case None => lookInBaseClasses + } + else lookInBaseClasses + } private var expandCount = 0 private final val expandLimit = 10 diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala index eaad12c0ed..e5a49f8358 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala @@ -224,8 +224,12 @@ abstract class TreeBrowsers { t.symbol.owner.toString else "NoSymbol has no owner") - if ((t.symbol ne null) && t.symbol.isType) - str.append("\ntermSymbol: " + t.symbol.tpe.termSymbol + "\ntypeSymbol: " + t.symbol.tpe.typeSymbol) + if ((t.symbol ne null) && t.symbol.isType) { + str.append("\ntermSymbol: " + t.symbol.tpe.termSymbol + + "\ntypeSymbol: " + t.symbol.tpe.typeSymbol) + if (t.symbol.isTypeSkolem) + str.append("\nSkolem of: " + t.symbol.deSkolemize) + } str.append("\nSymbol tpe: ") if (t.symbol ne null) { str.append(t.symbol.tpe).append("\n") @@ -562,7 +566,8 @@ abstract class TreeBrowsers { if ((s ne null) && (s != NoSymbol)) { var str = flagsToString(s.flags) if (s.isStaticMember) str = str + " isStatic "; - str + " annotations: " + s.annotations.mkString("", " ", "") + (str + " annotations: " + s.annotations.mkString("", " ", "") + + (if (s.isTypeSkolem) "\ndeSkolemized annotations: " + s.deSkolemize.annotations.mkString("", " ", "") else "")) } else "" } diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 9f2065f297..f8678ce24e 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -191,6 +191,19 @@ abstract class TreeGen def mkAsInstanceOf(value: Tree, tpe: Type, any: Boolean = true): Tree = mkTypeApply(value, tpe, (if (any) Any_asInstanceOf else Object_asInstanceOf)) + /** Cast `tree' to 'pt', unless tpe is a subtype of pt, or pt is Unit. */ + def maybeMkAsInstanceOf(tree: Tree, pt: Type, tpe: Type, beforeRefChecks: Boolean = false): Tree = + if ((pt == UnitClass.tpe) || (tpe <:< pt)) { + log("no need to cast from " + tpe + " to " + pt) + tree + } else + atPos(tree.pos) { + if (beforeRefChecks) + TypeApply(mkAttributedSelect(tree, Any_asInstanceOf), List(TypeTree(pt))) + else + mkAsInstanceOf(tree, pt) + } + def mkClassOf(tp: Type): Tree = Literal(Constant(tp)) setType ConstantType(Constant(tp))// ClassType(tp) diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 9097dd460e..3640b6825b 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -935,19 +935,34 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable => lazy val EmptyTreeTypeSubstituter = new TreeTypeSubstituter(List(), List()) - class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Traverser { + /** Substitute symbols in 'from' with symbols in 'to'. Returns a new + * tree using the new symbols and whose Ident and Select nodes are + * name-consistent with the new symbols. + */ + class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Transformer { val symSubst = new SubstSymMap(from, to) - override def traverse(tree: Tree) { + override def transform(tree: Tree): Tree = { def subst(from: List[Symbol], to: List[Symbol]) { if (!from.isEmpty) if (tree.symbol == from.head) tree setSymbol to.head else subst(from.tail, to.tail) } + if (tree.tpe ne null) tree.tpe = symSubst(tree.tpe) - if (tree.hasSymbol) subst(from, to) - super.traverse(tree) + if (tree.hasSymbol) { + subst(from, to) + tree match { + case Ident(name0) if tree.symbol != NoSymbol => + treeCopy.Ident(tree, tree.symbol.name) + case Select(qual, name0) => + treeCopy.Select(tree, transform(qual), tree.symbol.name) + case _ => + super.transform(tree) + } + } else + super.transform(tree) } - override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate) + def apply[T <: Tree](tree: T): T = transform(tree).asInstanceOf[T] override def toString() = "TreeSymSubstituter("+from+","+to+")" } 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/doc/html/HtmlFactory.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala index f695d0067f..348dc4b26c 100644 --- a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala @@ -7,10 +7,10 @@ package scala.tools.nsc package doc package html +import model._ + import java.io.{ File => JFile } import io.{ Streamable, Directory } -import reporters.Reporter -import model._ import scala.collection._ /** A class that can generate Scaladoc sites to some fixed root folder. @@ -27,16 +27,15 @@ class HtmlFactory(val universe: Universe) { * that document a model extracted from a compiler run. * @param model The model to generate in the form of a sequence of packages. */ def generate(universe: Universe): Unit = { + def copyResource(subPath: String) { val bytes = new Streamable.Bytes { val inputStream = getClass.getResourceAsStream("/scala/tools/nsc/doc/html/resource/" + subPath) assert(inputStream != null) - } . toByteArray() - + }.toByteArray val dest = Directory(siteRoot) / subPath dest.parent.createDirectory() val out = dest.toFile.bufferedOutput() - try out.write(bytes, 0, bytes.length) finally out.close() } @@ -64,11 +63,12 @@ class HtmlFactory(val universe: Universe) { val written = mutable.HashSet.empty[DocTemplateEntity] - def writeTemplate(tpl: DocTemplateEntity): Unit = { - new page.Template(tpl) writeFor this - written += tpl - tpl.templates filter { t => !(written contains t) } map (writeTemplate(_)) - } + def writeTemplate(tpl: DocTemplateEntity): Unit = + if (!(written contains tpl)) { + new page.Template(tpl) writeFor this + written += tpl + tpl.templates map (writeTemplate(_)) + } writeTemplate(universe.rootPackage) diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index 77b8d96e1c..4a6a9de032 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -188,7 +188,7 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage { { val inDefTpls = mbr.inDefinitionTemplates if (inDefTpls.tail.isEmpty && (inDefTpls.head == mbr.inTemplate)) NodeSeq.Empty else { <div class="block"> - definition classes: { templatesToHtml(inDefTpls, xml.Text(" ⇐ ")) } + definition classes: { templatesToHtml(inDefTpls, xml.Text(" → ")) } </div> } } diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 3968d3483c..64dfbfb160 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -108,10 +108,12 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme } def deprecation = if (sym.isDeprecated) - Some(sym.deprecationMessage map (x => parseWiki(x, NoPosition)) getOrElse Body(Nil)) + Some(sym.deprecationMessage match { + case Some(msg) => parseWiki(msg, NoPosition) + case None =>Body(Nil) + }) else - comment flatMap (_.deprecated) - + comment flatMap { _.deprecated } def inheritedFrom = if (inTemplate.sym == this.sym.owner || inTemplate.sym.isPackage) Nil else makeTemplate(this.sym.owner) :: (sym.allOverriddenSymbols map { os => makeTemplate(os.owner) }) @@ -162,7 +164,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme case _ => } } - sym.ancestors filter (_ != ScalaObjectClass) map makeTemplate + sym.ancestors filter (_ != ScalaObjectClass) map { makeTemplate(_) } } private lazy val subClassesCache = mutable.Buffer.empty[DocTemplateEntity] def registerSubClass(sc: DocTemplateEntity) = { @@ -198,13 +200,21 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme abstract class NonTemplateMemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends MemberImpl(sym, inTpl) with NonTemplateMemberEntity { override def qualifiedName = optimize(inTemplate.qualifiedName + "#" + name) lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "#" + name) + def isUseCase = sym.isSynthetic + } + + abstract class NonTemplateParamMemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends NonTemplateMemberImpl(sym, inTpl) { + def valueParams = + sym.paramss map { ps => (ps.zipWithIndex) map { case (p, i) => + if (p.nameString contains "$") makeValueParam(p, inTpl, optimize("arg" + i)) else makeValueParam(p, inTpl) + }} } abstract class ParameterImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends EntityImpl(sym, inTpl) with ParameterEntity { override def inTemplate = inTpl } - private trait StdTypeBounds extends EntityImpl { + private trait TypeBoundsImpl extends EntityImpl { def lo = sym.info.normalize match { case TypeBounds(lo, hi) if lo.typeSymbol != NothingClass => Some(makeType(lo, inTemplate, sym)) case _ => None @@ -219,10 +229,14 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme /** */ def normalizeTemplate(aSym: Symbol): Symbol = aSym match { - case null | EmptyPackage | NoSymbol => normalizeTemplate(RootPackage) - case ScalaObjectClass | ObjectClass => normalizeTemplate(AnyRefClass) - case _ if aSym.isModuleClass || aSym.isPackageObject => normalizeTemplate(aSym.sourceModule) - case _ => aSym + case null | EmptyPackage | NoSymbol => + normalizeTemplate(RootPackage) + case ScalaObjectClass | ObjectClass => + normalizeTemplate(AnyRefClass) + case _ if aSym.isModuleClass || aSym.isPackageObject => + normalizeTemplate(aSym.sourceModule) + case _ => + aSym } def makeRootPackage: Option[PackageImpl] = @@ -305,7 +319,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme List(sym.constrParamAccessors map (makeValueParam(_, this))) val constructors = members collect { case d: Constructor => d } - def primaryConstructor = constructors find (_.isPrimary) + def primaryConstructor = constructors find { _.isPrimary } def isCaseClass = sym.isClass && sym.hasFlag(Flags.CASE) } else @@ -316,44 +330,31 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme def makeMember(aSym: Symbol, inTpl: => DocTemplateImpl): List[MemberImpl] = { def makeMember0(bSym: Symbol): Option[MemberImpl] = { - abstract class MakeMemberTemplateImpl extends NonTemplateMemberImpl(bSym, inTpl) { - def isUseCase = bSym.isSynthetic - } - trait MethodParams extends MakeMemberTemplateImpl { - def valueParams = - sym.paramss map { ps => - ps.zipWithIndex map { case (p, i) => - if (p.nameString contains "$") makeValueParam(p, inTemplate, optimize("arg" + i)) - else makeValueParam(p, inTemplate) - } - } - } - if (bSym.isGetter && bSym.accessed.isMutable) - Some(new MakeMemberTemplateImpl with Val { + Some(new NonTemplateMemberImpl(bSym, inTpl) with Val { override def isVar = true }) else if (bSym.isMethod && !bSym.isGetterOrSetter && !bSym.isConstructor) - Some(new MakeMemberTemplateImpl with Def with MethodParams { + Some(new NonTemplateParamMemberImpl(bSym, inTpl) with Def { override def isDef = true def typeParams = sym.tpe.typeParams map (makeTypeParam(_, inTpl)) }) else if (bSym.isConstructor) - Some(new MakeMemberTemplateImpl with Constructor with MethodParams { + Some(new NonTemplateParamMemberImpl(bSym, inTpl) with Constructor { override def isConstructor = true def isPrimary = sym.isPrimaryConstructor }) else if (bSym.isGetter) // Scala field accessor or Java field - Some(new MakeMemberTemplateImpl with Val { + Some(new NonTemplateMemberImpl(bSym, inTpl) with Val { override def isVal = true }) else if (bSym.isAbstractType) - Some(new MakeMemberTemplateImpl with AbstractType with StdTypeBounds { + Some(new NonTemplateMemberImpl(bSym, inTpl) with TypeBoundsImpl with AbstractType { override def isAbstractType = true }) else if (bSym.isAliasType) - Some(new MakeMemberTemplateImpl with AliasType { + Some(new NonTemplateMemberImpl(bSym, inTpl) with AliasType { override def isAliasType = true def alias = makeType(sym.tpe, inTpl, sym) }) @@ -364,19 +365,21 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme else None } + if ((!aSym.isPackage && aSym.sourceFile == null) || !localShouldDocument(aSym) || aSym.isModuleClass || aSym.isPackageObject || aSym.isMixinConstructor) Nil else { val allSyms = useCases(aSym, inTpl.sym) map { case (bSym, bComment, bPos) => addCommentBody(bSym, inTpl, bComment, bPos) } - (allSyms :+ aSym) flatMap makeMember0 + (allSyms :+ aSym) flatMap { makeMember0(_) } } + } /** */ def makeTypeParam(aSym: Symbol, inTpl: => DocTemplateImpl): TypeParam = { - new ParameterImpl(aSym, inTpl) with TypeParam with StdTypeBounds { + new ParameterImpl(aSym, inTpl) with TypeBoundsImpl with TypeParam { def isTypeParam = true def isValueParam = false def variance: String = { @@ -492,10 +495,11 @@ class ModelFactory(val global: Global, val settings: doc.Settings) extends Comme val name = optimize(nameBuffer.toString) } - def templateShouldDocument(aSym: Symbol): Boolean = { - (aSym.isPackageClass || (aSym.sourceFile != null)) && localShouldDocument(aSym) && ( aSym.owner == NoSymbol || templateShouldDocument(aSym.owner) ) - } + def templateShouldDocument(aSym: Symbol): Boolean = + (aSym.isPackageClass || (aSym.sourceFile != null)) && localShouldDocument(aSym) && + ( aSym.owner == NoSymbol || templateShouldDocument(aSym.owner) ) def localShouldDocument(aSym: Symbol): Boolean = !aSym.isPrivate && (aSym.isProtected || aSym.privateWithin == NoSymbol) && !aSym.isSynthetic + } diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala index 1a0bf37a84..0aff68ab02 100644 --- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala @@ -106,7 +106,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => * splits the whole comment into main body and tag bodies, then runs the `WikiParser` on each body before creating * the comment instance. * - * @param body The body of the comment parsed until now. + * @param docBody The body of the comment parsed until now. * @param tags All tags parsed until now. * @param lastTagKey The last parsed tag, or `None` if the tag section hasn't started. Lines that are not tagged * are part of the previous tag or, if none exists, of the body. @@ -119,17 +119,17 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => if (before.trim != "") parse0(docBody, tags, lastTagKey, before :: ("{{{" + after) :: ls, false) else if (after.trim != "") - parse0(docBody, tags, lastTagKey, after :: ls, true) + parse0(docBody, tags, lastTagKey, "{{{" :: after :: ls, true) else - parse0(docBody, tags, lastTagKey, ls, true) + parse0(docBody + endOfLine + "{{{", tags, lastTagKey, ls, true) case CodeBlockEnd(before, after) :: ls => if (before.trim != "") parse0(docBody, tags, lastTagKey, before :: ("}}}" + after) :: ls, true) else if (after.trim != "") - parse0(docBody, tags, lastTagKey, after :: ls, false) + parse0(docBody, tags, lastTagKey, "}}}" :: after :: ls, false) else - parse0(docBody, tags, lastTagKey, ls, false) + parse0(docBody + endOfLine + "}}}", tags, lastTagKey, ls, false) case SymbolTag(name, sym, body) :: ls if (!inCodeBlock) => val key = SymbolTagKey(name, sym) @@ -269,11 +269,11 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /** {{{ block ::= code | title | hrule | para }}} */ def block(): Block = { - if (check("{{{")) + if (checkSkipInitWhitespace("{{{")) code() - else if (check("=")) + else if (checkSkipInitWhitespace("=")) title() - else if (check("----")) + else if (checkSkipInitWhitespace("----")) hrule() else if (checkList) listBlock @@ -284,7 +284,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /** Checks if the current line is formed with more than one space and one the listStyles */ def checkList = - countWhitespace > 0 && listStyles.keysIterator.indexWhere(checkSkipWhitespace(_)) >= 0 + countWhitespace > 0 && listStyles.keysIterator.indexWhere(checkSkipInitWhitespace(_)) >= 0 /** {{{ * nListBlock ::= nLine { mListBlock } @@ -329,6 +329,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => listLevel(indentStr, style, constructor) } def code(): Block = { + jumpWhitespace() jump("{{{") readUntil("}}}") if (char == endOfText) @@ -341,6 +342,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /** {{{ title ::= ('=' inline '=' | "==" inline "==" | ...) '\n' }}} */ def title(): Block = { + jumpWhitespace() val inLevel = repeatJump("=") val text = inline(check(Array.fill(inLevel)('='))) val outLevel = repeatJump("=", inLevel) @@ -352,6 +354,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /** {{{ hrule ::= "----" { '-' } '\n' }}} */ def hrule(): Block = { + jumpWhitespace() repeatJump("-") blockEnded("horizontal rule") HorizontalRule() @@ -504,11 +507,19 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => def checkParaEnded(): Boolean = { (char == endOfText) || ((char == endOfLine) && { - check(Array(endOfLine, endOfLine)) || - check(Array(endOfLine, '=')) || - check(Array(endOfLine, '{', '{', '{')) || - check(Array(endOfLine, ' ', '-', ' ')) || - check(Array(endOfLine, '\u003D')) + val poff = offset + val pc = char + nextChar() // read EOL + val ok = { + checkSkipInitWhitespace(Array(endOfLine)) || + checkSkipInitWhitespace(Array('=')) || + checkSkipInitWhitespace(Array('{', '{', '{')) || + checkSkipInitWhitespace(Array(' ', '-', ' ')) || + checkSkipInitWhitespace(Array('\u003D')) + } + offset = poff + char = pc + ok }) } @@ -549,22 +560,26 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => ok } - def checkSkipWhitespace(chars: Array[Char]): Boolean = { - assert(chars.head!=' ') // or it makes no sense + def checkSkipInitWhitespace(chars: Array[Char]): Boolean = { val poff = offset val pc = char - jumpWhitespace - val ok = jump(chars) + jumpWhitespace() + val (ok0, chars0) = + if (chars.head == ' ') + (offset > poff, chars.tail) + else + (true, chars) + val ok = ok0 && jump(chars0) offset = poff char = pc ok } - def countWhitespace:Int = { + def countWhitespace: Int = { var count = 0 val poff = offset val pc = char - while (isWhitespace(char) && char!=endOfText) { + while (isWhitespace(char) && char != endOfText) { nextChar() count += 1 } diff --git a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala index 3f59824ec2..52135ebcd6 100644 --- a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala +++ b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala @@ -112,7 +112,8 @@ class RefinedBuildManager(val settings: Settings) extends Changes with BuildMana // For testing purposes only, order irrelevant for compilation def toStringSet(set: Set[AbstractFile]): String = { - val s = set.toList sortBy (_.name) + val s = set.toList sortBy (_.name) map + (_.toString.replaceAll(java.util.regex.Matcher.quoteReplacement("\\"), "/")) s.mkString("Set(", ", ", ")") } diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala index 887bf4b55d..66a0da3a0f 100644 --- a/src/compiler/scala/tools/nsc/io/File.scala +++ b/src/compiler/scala/tools/nsc/io/File.scala @@ -77,7 +77,7 @@ with Streamable.Chars { /** Obtains a OutputStream. */ def outputStream(append: Boolean = false) = new FileOutputStream(jfile, append) def bufferedOutput(append: Boolean = false) = new BufferedOutputStream(outputStream(append)) - def printStream(append: Boolean = false) = new PrintStream(bufferedOutput(append)) + def printStream(append: Boolean = false) = new PrintStream(outputStream(append), true) /** Obtains an OutputStreamWriter wrapped around a FileOutputStream. * This should behave like a less broken version of java.io.FileWriter, @@ -136,4 +136,16 @@ with Streamable.Chars { true } + + /** Reflection since we're into the java 6+ API. + */ + def setExecutable(executable: Boolean, ownerOnly: Boolean = true): Boolean = { + type JBoolean = java.lang.Boolean + val method = + try classOf[JFile].getMethod("setExecutable", classOf[Boolean], classOf[Boolean]) + catch { case _: NoSuchMethodException => return false } + + try method.invoke(jfile, executable: JBoolean, ownerOnly: JBoolean).asInstanceOf[JBoolean].booleanValue + catch { case _: Exception => false } + } } diff --git a/src/compiler/scala/tools/nsc/io/Process.scala b/src/compiler/scala/tools/nsc/io/Process.scala index 746c5f1a8d..698082d19e 100644 --- a/src/compiler/scala/tools/nsc/io/Process.scala +++ b/src/compiler/scala/tools/nsc/io/Process.scala @@ -6,6 +6,7 @@ package scala.tools.nsc package io import concurrent.ThreadRunner +import scala.annotation.tailrec import scala.util.Properties.{ isWin, isMac, lineSeparator } import scala.util.control.Exception.catching import java.lang.{ Process => JProcess, ProcessBuilder => JProcessBuilder } @@ -139,7 +140,7 @@ class Process(processCreator: () => JProcess) extends Iterable[String] { def waitFor() = process.waitFor() def destroy() = process.destroy() - def rerun() = new Process(processCreator) + def rerun() = new Process(processCreator) def slurp() = _out.slurp() def stdout = iterator @@ -148,26 +149,32 @@ class Process(processCreator: () => JProcess) extends Iterable[String] { lazy val stdin = new PrintWriter(_in, true) class StreamedConsumer(in: InputStream) extends Thread with Iterable[String] { - private val queue = new LinkedBlockingQueue[String] - private val reader = new BufferedReader(new InputStreamReader(in)) + private val queue = new LinkedBlockingQueue[String] + private val reader = new BufferedReader(new InputStreamReader(in)) - def slurp(): String = { + private def finish() { + // make sure this thread is complete, and close the process's stdin join() + _in.close() + } + + def slurp(): String = { + finish() queue.toArray map (_ + lineSeparator) mkString } def iterator = { - join() // make sure this thread is complete + finish() new Iterator[String] { val it = queue.iterator() def hasNext = it.hasNext def next = it.next } } - override def run() { + @tailrec override final def run() { reader.readLine match { case null => - in.close() + reader.close() case x => queue put x run() diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index 44ab9c6062..8012b9389b 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -4,15 +4,13 @@ */ // $Id$ -package scala.tools.nsc +package scala.tools +package nsc package settings import io.AbstractFile -import util.{ ClassPath, CommandLineParser } -import annotation.elidable import scala.tools.util.StringOps import scala.collection.mutable.ListBuffer -import interpreter.{ returning } /** A mutable Settings object. */ @@ -84,7 +82,7 @@ class MutableSettings(val errorFn: String => Unit) extends AbsSettings with Scal /** Split the given line into parameters. */ - def splitParams(line: String) = CommandLineParser.tokenize(line, errorFn) + def splitParams(line: String) = cmd.Parser.tokenize(line, errorFn) /** Returns any unprocessed arguments. */ @@ -426,7 +424,7 @@ class MutableSettings(val errorFn: String => Unit) extends AbsSettings with Scal prependPath: StringSetting, appendPath: StringSetting) extends StringSetting(name, arg, descr, default) { - import ClassPath.join + import util.ClassPath.join def prepend(s: String) = prependPath.value = join(s, prependPath.value) def append(s: String) = appendPath.value = join(appendPath.value, s) diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index f9fd996add..1b6b8297ef 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -4,22 +4,18 @@ */ // $Id$ -package scala.tools.nsc +package scala.tools +package nsc package settings -import io.AbstractFile -import util.{ ClassPath, SourceFile, CommandLineParser } import annotation.elidable -import scala.tools.util.{ PathResolver, StringOps } -import scala.collection.mutable.{ HashSet, ListBuffer } -import scala.collection.immutable.TreeSet -import interpreter.{ returning } +import scala.tools.util.PathResolver.Defaults +import scala.collection.mutable.HashSet trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { self: MutableSettings => - import PathResolver.{ Defaults, Environment } - import Defaults.{ scalaUserClassPath } + import Defaults.scalaUserClassPath /** Set of settings */ protected lazy val allSettings = HashSet[Setting]() @@ -45,6 +41,8 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { val optimise = BooleanSetting ("-optimise", "Generates faster bytecode by applying optimisations to the program") . withAbbreviation("-optimize") . withPostSetHook(_ => List(inline, Xcloselim, Xdce) foreach (_.value = true)) + val nospecialization = BooleanSetting ("-no-specialization", "Ignore @specialize annotations.") + /** * -X "Advanced" settings @@ -126,7 +124,6 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { ChoiceSetting ("-Ystruct-dispatch", "Selects dispatch method for structural refinement method calls", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") . withHelpSyntax("-Ystruct-dispatch:<method>") - val specialize = BooleanSetting ("-Yspecialize", "Specialize generic code on types.") val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") val Yidedebug = BooleanSetting ("-Yide-debug", "Generate, validate and output trees using the interactive compiler.") val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "Compile using the specified build manager", List("none", "refined", "simple"), "none") . 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/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala index 2978d6cb0a..b0cc3a5340 100644 --- a/src/compiler/scala/tools/nsc/symtab/Flags.scala +++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala @@ -45,7 +45,7 @@ object Flags extends reflect.generic.Flags { /** These modifiers appear in TreePrinter output. */ final val PrintableFlags: Long = ExplicitFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | - ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | BRIDGE | STATIC | VBRIDGE + ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | BRIDGE | STATIC | VBRIDGE | SPECIALIZED /** The two bridge flags */ final val BRIDGES = BRIDGE | VBRIDGE @@ -60,6 +60,13 @@ object Flags extends reflect.generic.Flags { /** Module flags inherited by their module-class */ final val ModuleToClassFlags: Long = AccessFlags | MODULE | PACKAGE | CASE | SYNTHETIC | JAVA + def getterFlags(fieldFlags: Long): Long = + ACCESSOR + + (if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER else fieldFlags & ~PRESUPER | STABLE) + + def setterFlags(fieldFlags: Long): Long = + getterFlags(fieldFlags) & ~STABLE & ~CASEACCESSOR + private def listToString(ss: List[String]): String = ss.filter("" !=).mkString("", " ", "") @@ -98,6 +105,7 @@ object Flags extends reflect.generic.Flags { else if (flag == TRANS_FLAG ) "<trans-flag>" else if (flag == LOCKED ) "<locked>" else if (flag == LAZY ) "lazy" + else if (flag == SPECIALIZED ) "<specialized>" else flag.toInt match { case IMPLICIT => "implicit" case FINAL => "final" diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index f50ace8426..4c0c1ec739 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -331,6 +331,14 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => final def newRefinementClass(pos: Position) = newClass(pos, nme.REFINE_CLASS_NAME.toTypeName) + /** Create a new getter for current symbol (which must be a field) + */ + final def newGetter: Symbol = { + val getter = owner.newMethod(pos.focus, nme.getterName(name)).setFlag(getterFlags(flags)) + getter.privateWithin = privateWithin + getter.setInfo(MethodType(List(), tpe)) + } + final def newErrorClass(name: Name) = { val clazz = newClass(pos, name).setFlag(SYNTHETIC | IS_ERROR) clazz.setInfo(ClassInfoType(List(), new ErrorScope(this), clazz)) @@ -389,10 +397,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 @@ -903,7 +910,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => else { val current = phase try { - while (phase.keepsTypeParams) phase = phase.prev + while (phase.keepsTypeParams && (phase.prev ne NoPhase)) phase = phase.prev + if (phase ne current) phase = phase.next rawInfo.typeParams } finally { phase = current diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 4211392b88..2cd690fbbf 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -1045,6 +1045,7 @@ trait Types extends reflect.generic.Types { self: SymbolTable => override def typeSymbol = sym override def underlying: Type = sym.typeOfThis override def isVolatile = false + override def isHigherKinded = sym.isRefinementClass && underlying.isHigherKinded override def prefixString = if (settings.debug.value) sym.nameString + ".this." else if (sym.isRoot || sym.isEmptyPackageClass || sym.isInterpreterWrapper || sym.isScalaPackageClass) "" @@ -5158,7 +5159,7 @@ A type's typeSymbol should never be inspected directly. // Errors and Diagnostics ----------------------------------------------------- /** A throwable signalling a type error */ - class TypeError(var pos: Position, val msg: String) extends Throwable(msg) with ControlThrowable { + class TypeError(var pos: Position, val msg: String) extends Throwable(msg) { def this(msg: String) = this(NoPosition, msg) } diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ea759b30f5..94d52bc1cb 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -31,6 +31,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. def newTransformer(unit: CompilationUnit): Transformer = new ErasureTransformer(unit) + override def keepsTypeParams = false + // -------- erasure on types -------------------------------------------------------- /** An extractor objec for generic arrays */ diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index dad654c967..f2b896dc96 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -354,8 +354,7 @@ abstract class ExplicitOuter extends InfoTransform localTyper typed (DEF(method) === { new ChangeOwnerTraverser(currentOwner, method) traverse guard - new TreeSymSubstituter(vs, method.paramss.head) traverse guard - guard + new TreeSymSubstituter(vs, method.paramss.head) transform (guard) }) } diff --git a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala index 05fbe06174..9872705dfc 100644 --- a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala +++ b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala @@ -23,7 +23,7 @@ trait InfoTransform extends Transform { new Phase(prev) protected def changesBaseClasses = true - protected def keepsTypeParams = false + protected def keepsTypeParams = true class Phase(prev: scala.tools.nsc.Phase) extends super.Phase(prev) { override val keepsTypeParams = InfoTransform.this.keepsTypeParams diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index b24b263b7a..6ed0bfcccb 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -331,6 +331,17 @@ abstract class LambdaLift extends InfoTransform { lifted(MethodType(sym.info.params ::: addParams, sym.info.resultType))) treeCopy.DefDef(tree, mods, name, tparams, List(vparams ::: freeParams), tpt, rhs) case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) => + // Disabled attempt to to add getters to freeParams + // this does not work yet. Problem is that local symbols need local names + // and references to local symbols need to be transformed into + // method calls to setters. + // def paramGetter(param: Symbol): Tree = { + // val getter = param.newGetter setFlag TRANS_FLAG resetFlag PARAMACCESSOR // mark because we have to add them to interface + // sym.info.decls.enter(getter) + // val rhs = Select(gen.mkAttributedThis(sym), param) setType param.tpe + // DefDef(getter, rhs) setPos tree.pos setType NoType + // } + // val newDefs = if (sym.isTrait) freeParams ::: (ps map paramGetter) else freeParams treeCopy.ClassDef(tree, mods, name, tparams, treeCopy.Template(impl, parents, self, body ::: freeParams)) } @@ -338,6 +349,38 @@ abstract class LambdaLift extends InfoTransform { tree } +/* Something like this will be necessary to eliminate the implementation + * restiction from paramGetter above: + * We need to pass getters to the interface of an implementation class. + private def fixTraitGetters(lifted: List[Tree]): List[Tree] = + for (stat <- lifted) yield stat match { + case ClassDef(mods, name, tparams, templ @ Template(parents, self, body)) + if stat.symbol.isTrait && !stat.symbol.isImplClass => + val iface = stat.symbol + lifted.find(l => l.symbol.isImplClass && l.symbol.toInterface == iface) match { + case Some(implDef) => + val impl = implDef.symbol + val implGetters = impl.info.decls.toList filter (_ hasFlag TRANS_FLAG) + if (implGetters.nonEmpty) { + val ifaceGetters = implGetters map { ig => + ig resetFlag TRANS_FLAG + val getter = ig cloneSymbol iface setFlag DEFERRED + iface.info.decls enter getter + getter + } + val ifaceGetterDefs = ifaceGetters map (DefDef(_, EmptyTree) setType NoType) + treeCopy.ClassDef( + stat, mods, name, tparams, + treeCopy.Template(templ, parents, self, body ::: ifaceGetterDefs)) + } else + stat + case None => + stat + } + case _ => + stat + } +*/ private def liftDef(tree: Tree): Tree = { val sym = tree.symbol if (sym.owner.isAuxiliaryConstructor && sym.isMethod) // # bug 1909 @@ -411,7 +454,7 @@ abstract class LambdaLift extends InfoTransform { override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = { def addLifted(stat: Tree): Tree = stat match { case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) => - val lifted = liftedDefs(stat.symbol).toList map addLifted + val lifted = /*fixTraitGetters*/(liftedDefs(stat.symbol).toList map addLifted) val result = treeCopy.ClassDef( stat, mods, name, tparams, treeCopy.Template(impl, parents, self, body ::: lifted)) liftedDefs -= stat.symbol diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index f76ab66aa4..5ced187128 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -84,6 +84,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { /** For a given class and concrete type arguments, give its specialized class */ val specializedClass: mutable.Map[(Symbol, TypeEnv), Symbol] = new mutable.HashMap + /** Returns the generic class that was specialized to 'cls', or + * 'cls' itself if cls is not a specialized subclass. + */ + def genericClass(cls: Symbol): Symbol = + if (cls.hasFlag(SPECIALIZED)) + cls.info.parents.head.typeSymbol + else + cls + /** Map a method symbol to a list of its specialized overloads in the same class. */ private val overloads: mutable.Map[Symbol, List[Overload]] = new mutable.HashMap[Symbol, List[Overload]] { override def default(key: Symbol): List[Overload] = Nil @@ -200,7 +209,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val (methparams, others) = tvars.toList.partition(_.owner.isMethod) val tvars1 = methparams sortBy (_.name.toString) val tvars2 = others sortBy (_.name.toString) - log("specName(" + sym + ") env " + env) + if (settings.debug.value) log("specName(" + sym + ") env " + env) specializedName(sym.name, tvars1 map env, tvars2 map env) } @@ -234,51 +243,30 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } - lazy val primitiveTypes = Map( - "Unit" -> definitions.UnitClass.tpe, - "Boolean" -> definitions.BooleanClass.tpe, - "Byte" -> definitions.ByteClass.tpe, - "Short" -> definitions.ShortClass.tpe, - "Char" -> definitions.CharClass.tpe, - "Int" -> definitions.IntClass.tpe, - "Long" -> definitions.LongClass.tpe, - "Float" -> definitions.FloatClass.tpe, - "Double" -> definitions.DoubleClass.tpe) - - - - /** Parse the given string into the list of types it contains. - * - * @param str comma-separated string of distinct primitive types. - */ - def parseTypes(str: String): List[Type] = { - if (str.trim == "") - List() - else { - val buf = new mutable.ListBuffer[Type] - for (t <- str.split(',')) - primitiveTypes.get(t.trim) match { - case Some(tpe) => buf += tpe - case None => - error("Invalid type " + t + ". Expected one of " + primitiveTypes.keysIterator.mkString("", ", ", ".")) - } - buf.toList - } - } - - /** Return the concrete types `sym' should be specialized at. + lazy val primitiveTypes = List( + definitions.UnitClass.tpe, + definitions.BooleanClass.tpe, + definitions.ByteClass.tpe, + definitions.ShortClass.tpe, + definitions.CharClass.tpe, + definitions.IntClass.tpe, + definitions.LongClass.tpe, + definitions.FloatClass.tpe, + definitions.DoubleClass.tpe) + + /** Return the concrete types `sym' should be specialized at. */ def concreteTypes(sym: Symbol): List[Type] = sym.getAnnotation(SpecializedClass) match { case Some(AnnotationInfo(_, args, _)) => args match { - case Literal(ct) :: _ => - val tpes = parseTypes(ct.stringValue) + case Nil => + log(sym + " specialized on everything") + primitiveTypes.toList + case _ => + val tpes = args.map(_.symbol.companionClass.tpe) log(sym + " specialized on " + tpes) tpes - case _ => - log(sym + " specialized on everything") - primitiveTypes.valuesIterator.toList } case _ => Nil @@ -336,12 +324,18 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { (s, tp) => s ++ specializedTypeVars(tp) } + private def specializedTypeVars(sym: Symbol): immutable.Set[Symbol] = + specializedTypeVars(atPhase(currentRun.typerPhase)(sym.info)) + /** Return the set of @specialized type variables mentioned by the given type. */ private def specializedTypeVars(tpe: Type): immutable.Set[Symbol] = tpe match { case TypeRef(pre, sym, args) => if (sym.isTypeParameter && sym.hasAnnotation(SpecializedClass)) specializedTypeVars(args) + sym - else + else if (sym.isTypeSkolem && sym.deSkolemize.hasAnnotation(SpecializedClass)) { + println("cought skolem without @specialized") + specializedTypeVars(args) + sym + } else specializedTypeVars(args) case PolyType(tparams, resTpe) => specializedTypeVars(tparams map (_.info)) ++ specializedTypeVars(resTpe) @@ -381,14 +375,42 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // unspecialized type parameters of 'cls' (cloned) var newClassTParams: List[Symbol] = Nil + // has to be a val in order to be computed early. It is later called + // within 'atPhase(next)', which would lead to an infinite cycle otherwise val specializedInfoType: Type = { val (_, unspecParams) = splitParams(clazz.info.typeParams) oldClassTParams = unspecParams newClassTParams = cloneSymbols(unspecParams, cls) - var parents = List(subst(env, clazz.tpe).subst(unspecParams, newClassTParams map (_.tpe))) + + def applyContext(tpe: Type) = + subst(env, tpe).subst(unspecParams, newClassTParams map (_.tpe)) + + /** Return a list of specialized parents to be re-mixed in a specialized subclass. + * Assuming env = [T -> Int] and + * class Integral[@specialized T] extends Numeric[T] + * and Numeric[U] is specialized on U, this produces List(Numeric$mcI). + * + * so that class Integral$mci extends Integral[Int] with Numeric$mcI. + */ + def specializedParents(parents: List[Type]): List[Type] = { + val res = new mutable.ListBuffer[Type] + for (p <- parents) { + val stp = specializedType(p) + if (stp != p) + if (p.typeSymbol.isTrait) res += stp + else if (currentRun.compiles(clazz)) + reporter.warning(clazz.pos, p.typeSymbol + " must be a trait. Specialized version of " + + clazz + " will inherit generic " + p) + } + res.reverse.toList + } + + var parents = List(applyContext(atPhase(currentRun.typerPhase)(clazz.tpe))) if (parents.head.typeSymbol.isTrait) parents = parents.head.parents.head :: parents - val infoType = ClassInfoType(parents, decls1, cls) + val extraSpecializedMixins = specializedParents(clazz.info.parents.map(applyContext)) + log("extraSpecializedMixins: " + extraSpecializedMixins) + val infoType = ClassInfoType(parents ::: extraSpecializedMixins, decls1, cls) if (newClassTParams.isEmpty) infoType else PolyType(newClassTParams, infoType) } @@ -433,13 +455,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { info(om) = if (original.isDeferred) Forward(original) else Implementation(original) log("forwardToOverlad: " + " original.isDeferred: " + original.isDeferred + " info(om): " + info(om)) typeEnv(om) = env ++ typeEnv(m) // add the environment for any method tparams + overloads(specMember) = Overload(om, typeEnv(om)) :: overloads(specMember) enterMember(om) } log("specializedClass: " + cls) for (m <- normMembers if needsSpecialization(outerEnv ++ env, m) && satisfiable(fullEnv)) { - log(" * looking at: " + m) + if (settings.debug.value) log(" * looking at: " + m) if (!m.isDeferred) concreteSpecMethods += m // specialized members have to be overridable. @@ -467,7 +490,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } else if (m.isDeferred) { // abstract methods val specMember = enterMember(m.cloneSymbol(cls)).setFlag(SPECIALIZED).resetFlag(DEFERRED) - log("deferred " + specMember.fullName + " is forwarded") + if (settings.debug.value) log("deferred " + specMember.fullName + " is forwarded") info(specMember) = new Forward(specMember) { override def target = m.owner.info.member(specializedName(m, env)) @@ -499,7 +522,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { enterMember(specVal) // create accessors - log("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name)) + if (settings.debug.value) + log("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name)) if (nme.isLocalName(m.name)) { val specGetter = mkAccessor(specVal, nme.localToGetter(specVal.name)).setInfo(MethodType(List(), specVal.info)) val origGetter = overrideIn(cls, m.getter(clazz)) @@ -534,7 +558,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { typeEnv(specClass) = fullEnv specClass.name = specializedName(specClass, fullEnv) enterMember(specClass) - log("entered specialized class with info " + specClass.fullName + ": " + specClass.info) + log("entered specialized class " + specClass.fullName) info(specClass) = SpecializedInnerClass(m, fullEnv) } } @@ -546,6 +570,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { if (m.isAnonymousClass) List(m) else { normalizeMember(m.owner, m, outerEnv) flatMap { normalizedMember => val ms = specializeMember(m.owner, normalizedMember, outerEnv, clazz.info.typeParams) +// atPhase(currentRun.typerPhase)(println("normalizedMember.info: " + normalizedMember.info)) // bring the info to the typer phase if (normalizedMember.isMethod) { val newTpe = subst(outerEnv, normalizedMember.info) if (newTpe != normalizedMember.info) // only do it when necessary, otherwise the method type might be at a later phase already @@ -578,7 +603,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * m$D[ U](x: Double, y: U) */ private def normalizeMember(owner: Symbol, sym: Symbol, outerEnv: TypeEnv): List[Symbol] = { - if (sym.isMethod && !sym.info.typeParams.isEmpty) { + if (settings.debug.value) log("normalizeMember: " + sym.fullName) + if (sym.isMethod && !atPhase(currentRun.typerPhase)(sym.typeParams.isEmpty)) { val (stps, tps) = splitParams(sym.info.typeParams) val res = sym :: (for (env <- specializations(stps) if needsSpecialization(env, sym)) yield { val keys = env.keysIterator.toList; @@ -624,7 +650,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { if (sym.isMethod) { // log("specializeMember " + sym + " with own stps: " + specializedTypes(sym.info.typeParams)) val tps1 = if (sym.isConstructor) tps filter (tp => sym.info.paramTypes.contains(tp)) else tps - val tps2 = tps1 intersect specializedTypeVars(sym.info).toList + val tps2 = tps1 intersect specializedTypeVars(sym).toList if (!sym.isDeferred) concreteSpecMethods += sym specializeOn(tps2) map {m => info(m) = SpecialOverload(sym, typeEnv(m)); m} @@ -657,12 +683,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val opc = new overridingPairs.Cursor(clazz) val oms = new mutable.ListBuffer[Symbol] while (opc.hasNext) { - log("\toverriding pairs: " + opc.overridden.fullName + ": " + opc.overridden.info - + " overridden by " + opc.overriding.fullName + ": " + opc.overriding.info) + if (settings.debug.value) + log("\toverriding pairs: " + opc.overridden.fullName + ": " + opc.overridden.info + + " overriden by " + opc.overriding.fullName + ": " + opc.overriding.info) if (opc.overriding.owner == clazz && !specializedTypeVars(opc.overridden.info).isEmpty) { - log("\t\tspecializedTVars: " + specializedTypeVars(opc.overridden.info)) + if (settings.debug.value) log("\t\tspecializedTVars: " + specializedTypeVars(opc.overridden.info)) val env = unify(opc.overridden.info, opc.overriding.info, emptyEnv) - log("\t\tenv: " + env + "isValid: " + if (settings.debug.value) + log("\t\tenv: " + env + "isValid: " + TypeEnv.isValid(env, opc.overridden) + " exists: " + opc.overridden.owner.info.decl(specializedName(opc.overridden, env))) if (!env.isEmpty @@ -680,7 +708,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case Some(NormalizedMember(target)) => typeEnv(om) = env ++ typeEnv(opc.overriding) Implementation(target) - case None => Implementation(opc.overriding) + case _ => Implementation(opc.overriding) } info(opc.overriding) = Forward(om) log("typeEnv(om) = " + typeEnv(om)) @@ -800,6 +828,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { PolyType(targs, ClassInfoType(parents, new Scope(specializeClass(clazz, typeEnv(clazz))), clazz)) case ClassInfoType(base, decls, clazz) if !clazz.isPackageClass => +// base.map(_.typeSymbol.info) val parents = base map specializedType log("transformInfo " + clazz + " with parents1: " + parents) val res = ClassInfoType(base map specializedType, new Scope(specializeClass(clazz, typeEnv(clazz))), clazz) @@ -932,12 +961,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { transformTrees(args)))) } else super.transform(tree) - case TypeApply(Select(qual, name), targs) if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) => - log("checking typeapp for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe) + case TypeApply(Select(qual, name), targs) + if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) => + if (settings.debug.value) log("checking typeapp for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe) val qual1 = transform(qual) specSym(qual1) match { case Some(specMember) => - log("found " + specMember) + if (settings.debug.value) log("found " + specMember) assert(symbol.info.typeParams.length == targs.length) val env = typeEnv(specMember) val residualTargs = @@ -951,31 +981,46 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case None => super.transform(tree) } - case Select(qual, name) if (!specializedTypeVars(symbol.info).isEmpty - && name != nme.CONSTRUCTOR) => - val qual1 = transform(qual) - log("checking for unification at " + tree + " with sym.tpe: " + symbol.tpe + " and tree.tpe: " + tree.tpe + " at " + tree.pos.line) - val env = unify(symbol.tpe, tree.tpe, emptyEnv) - log("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env) - if (!env.isEmpty) { - val specMember = overload(symbol, env) - if (specMember.isDefined) { - log("** routing " + tree + " to " + specMember.get.sym.fullName + " tree: " + Select(qual1, specMember.get.sym.name)) - localTyper.typedOperator(atPos(tree.pos)(Select(qual1, specMember.get.sym.name))) - } else { - val specMember = qual1.tpe.member(specializedName(symbol, env)) - if (specMember ne NoSymbol) { - log("** using spec member " + specMember) - localTyper.typed(atPos(tree.pos)(Select(qual1, specMember.name))) - } else + case Select(qual, name) => + if (settings.debug.value) + log("looking at Select: " + tree + " sym: " + symbol + ": " + symbol.info + "[tree.tpe: " + tree.tpe + "]") + //if (settings.debug.value) log("\toverloads: " + overloads.mkString("", "\n", "")) + if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) { + if (settings.debug.value) + log("checking for unification at " + tree + " with sym.tpe: " + symbol.tpe + " and tree.tpe: " + tree.tpe + " at " + tree.pos.line) + val env = unify(symbol.tpe, tree.tpe, emptyEnv) + log("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env) + if (!env.isEmpty) { + val specMember = overload(symbol, env) + if (specMember.isDefined) { + if (settings.debug.value) log("** routing " + tree + " to " + specMember.get.sym.fullName + " tree: " + Select(transform(qual), specMember.get.sym.name)) + localTyper.typedOperator(atPos(tree.pos)(Select(transform(qual), specMember.get.sym.name))) + } else { + val qual1 = transform(qual) + val specMember = qual1.tpe.member(specializedName(symbol, env)) + if (specMember ne NoSymbol) { + log("** using spec member " + specMember) + val tree1 = atPos(tree.pos)(Select(qual1, specMember)) + if (specMember.isMethod) + localTyper.typedOperator(tree1) + else + localTyper.typed(tree1) + } else + super.transform(tree) + } + } else + super.transform(tree) + } else overloads(symbol).find(_.sym.info =:= symbol.info) match { + case Some(specMember) => + val qual1 = transform(qual) + if (settings.debug.value) log("** routing " + tree + " to " + specMember.sym.fullName + " tree: " + Select(qual1, specMember.sym.name)) + localTyper.typedOperator(atPos(tree.pos)(Select(qual1, specMember.sym.name))) + case None => super.transform(tree) - } - } else - super.transform(tree) + } case PackageDef(pid, stats) => tree.symbol.info // make sure specializations have been performed - log("PackageDef owner: " + symbol) atOwner(tree, symbol) { val specMembers = implSpecClasses(stats) map localTyper.typed treeCopy.PackageDef(tree, pid, transformStats(stats ::: specMembers, symbol.moduleClass)) @@ -985,7 +1030,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val specMembers = makeSpecializedMembers(tree.symbol.enclClass) ::: (implSpecClasses(body) map localTyper.typed) if (!symbol.isPackageClass) (new CollectMethodBodies)(tree) - treeCopy.Template(tree, currentOwner.info.parents.map(TypeTree), self, + val parents1 = currentOwner.info.parents.zipWithIndex.map { + case (tpe, idx) => TypeTree(tpe) setPos parents(idx).pos + } + treeCopy.Template(tree, + parents1 /*currentOwner.info.parents.map(tpe => TypeTree(tpe) setPos parents.head.pos)*/, + self, atOwner(currentOwner)(transformTrees(body ::: specMembers))) case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) if info.isDefinedAt(symbol) => @@ -995,7 +1045,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { forwardCall(tree.pos, superRef, vparamss) } val tree1 = atPos(symbol.pos)(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, Block(List(t), Literal(())))) - log(tree1) localTyper.typed(tree1) } else info(symbol) match { @@ -1003,7 +1052,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { assert(body.isDefinedAt(target), "sym: " + symbol.fullName + " target: " + target.fullName) // we have an rhs, specialize it val tree1 = duplicateBody(ddef, target) - log("implementation: " + tree1) + if (settings.debug.value) log("implementation: " + tree1) val DefDef(mods, name, tparams, vparamss, tpt, rhs) = tree1 treeCopy.DefDef(tree1, mods, name, tparams, vparamss, tpt, transform(rhs)) @@ -1035,7 +1084,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } else { // we have an rhs, specialize it val tree1 = duplicateBody(ddef, target) - log("implementation: " + tree1) + if (settings.debug.value) log("implementation: " + tree1) val DefDef(mods, name, tparams, vparamss, tpt, rhs) = tree1 treeCopy.DefDef(tree1, mods, name, tparams, vparamss, tpt, transform(rhs)) } @@ -1046,16 +1095,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val fun = Apply(Select(This(symbol.owner), original), makeArguments(original, vparamss.head)) - maybeCastTo(symbol.owner.info.memberType(symbol).finalResultType, - symbol.owner.info.memberType(original).finalResultType, - fun) + gen.maybeMkAsInstanceOf(fun, + symbol.owner.thisType.memberType(symbol).finalResultType, + symbol.owner.thisType.memberType(original).finalResultType) }) log("created " + t) localTyper.typed(t) case fwd @ Forward(_) => val rhs1 = forwardCall(tree.pos, gen.mkAttributedRef(symbol.owner.thisType, fwd.target), vparamss) - log("completed forwarder to specialized overload: " + fwd.target + ": " + rhs1) + if (settings.debug.value) + log("completed forwarder to specialized overload: " + fwd.target + ": " + rhs1) localTyper.typed(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs1)) case SpecializedAccessor(target) => @@ -1069,7 +1119,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case ValDef(mods, name, tpt, rhs) if symbol.hasFlag(SPECIALIZED) => assert(body.isDefinedAt(symbol.alias)) val tree1 = treeCopy.ValDef(tree, mods, name, tpt, body(symbol.alias).duplicate) - log("now typing: " + tree1 + " in " + tree.symbol.owner.fullName) + if (settings.debug.value) log("now typing: " + tree1 + " in " + tree.symbol.owner.fullName) val d = new Duplicator d.retyped(localTyper.context1.asInstanceOf[d.Context], tree1, @@ -1077,8 +1127,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { symbol.enclClass, typeEnv(symbol.alias) ++ typeEnv(tree.symbol)) - case Apply(Select(Super(qual, name), name1), args) => - val res = localTyper.typed(Apply(Select(Super(qual, name), name1), args)) + case Apply(sel @ Select(sup @ Super(qual, name), name1), args) => + val res = localTyper.typed( + Apply(Select(Super(qual, name) setPos sup.pos, name1) setPos sel.pos, args) setPos tree.pos) log("retyping call to super, from: " + symbol + " to " + res.symbol) res @@ -1095,10 +1146,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private def duplicateBody(tree: DefDef, target: Symbol): Tree = { val symbol = tree.symbol - log("specializing body of" + symbol.fullName + ": " + symbol.info) + if (settings.debug.value) log("specializing body of" + symbol.fullName + ": " + symbol.info) val DefDef(mods, name, tparams, vparamss, tpt, _) = tree val (_, origtparams) = splitParams(target.typeParams) - log("substituting " + origtparams + " for " + symbol.typeParams) + if (settings.debug.value) log("substituting " + origtparams + " for " + symbol.typeParams) // skolemize type parameters val (oldtparams, newtparams) = reskolemize(tparams) @@ -1146,17 +1197,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { /** All private members that are referenced are made protected, * in order to be accessible from specialized subclasses. */ - override def traverse(tree: Tree): Unit = tree match { + override def transform(tree: Tree): Tree = tree match { case Select(qual, name) => if (tree.symbol.hasFlag(PRIVATE | PROTECTED)) { log("changing private flag of " + tree.symbol) // tree.symbol.resetFlag(PRIVATE).setFlag(PROTECTED) tree.symbol.resetFlag(PRIVATE | PROTECTED) } - super.traverse(tree) + super.transform(tree) case _ => - super.traverse(tree) + super.transform(tree) } } @@ -1240,6 +1291,26 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } mbrs.toList } + + /** Create specialized class definitions */ + def implSpecClasses(trees: List[Tree]): List[Tree] = { + val buf = new mutable.ListBuffer[Tree] + for (tree <- trees) + tree match { + case ClassDef(_, _, _, impl) => + tree.symbol.info // force specialization + for (((sym1, env), specCls) <- specializedClass if sym1 == tree.symbol) { + val parents = specCls.info.parents.map(TypeTree) + buf += + ClassDef(specCls, atPos(impl.pos)(Template(parents, emptyValDef, List())) + .setSymbol(specCls.newLocalDummy(sym1.pos))) setPos tree.pos + log("created synthetic class: " + specCls + " of " + sym1 + " in env: " + env) + } + case _ => + } + log(buf) + buf.toList + } } private def forwardCall(pos: util.Position, receiver: Tree, paramss: List[List[ValDef]]): Tree = { @@ -1247,25 +1318,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { atPos(pos) { (receiver /: argss) (Apply) } } - /** Create specialized class definitions */ - def implSpecClasses(trees: List[Tree]): List[Tree] = { - val buf = new mutable.ListBuffer[Tree] - for (tree <- trees) - tree match { - case ClassDef(_, _, _, impl) => - tree.symbol.info // force specialization - for (((sym1, env), specCls) <- specializedClass if sym1 == tree.symbol) { - buf += - ClassDef(specCls, Template(specCls.info.parents map TypeTree, emptyValDef, List()) - .setSymbol(specCls.newLocalDummy(sym1.pos))) - log("created synthetic class: " + specCls + " of " + sym1 + " in env: " + env) - } - case _ => - } - log(buf) - buf.toList - } - /** Concrete methods that use a specialized type, or override such methods. */ private val concreteSpecMethods: mutable.Set[Symbol] = new mutable.HashSet @@ -1288,15 +1340,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { else tp.info.bounds.hi } - /** Cast `tree' to 'pt', unless tpe is a subtype of pt, or pt is Unit. */ - def maybeCastTo(pt: Type, tpe: Type, tree: Tree): Tree = - if ((pt == definitions.UnitClass.tpe) || (tpe <:< pt)) { - log("no need to cast from " + tpe + " to " + pt) - tree - } else - gen.mkAsInstanceOf(tree, pt) - - private def makeArguments(fun: Symbol, vparams: List[Symbol]): List[Tree] = { def needsCast(tp1: Type, tp2: Type): Boolean = !(tp1 <:< tp2) diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index 519ad1b0bf..635608520d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -33,6 +33,8 @@ trait Analyzer extends AnyRef val runsRightAfter = None def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) { override val checkable = false + override def keepsTypeParams = false + def apply(unit: CompilationUnit) { newNamer(rootContext(unit)).enterSym(unit.body) } @@ -71,6 +73,7 @@ trait Analyzer extends AnyRef val runsAfter = List[String]() val runsRightAfter = Some("packageobjects") def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) { + override def keepsTypeParams = false resetTyper() override def run { val start = startTimer(typerNanos) diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 7ca2ff81bb..1dbeb0afd9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -85,6 +85,15 @@ abstract class Duplicators extends Analyzer { typeRef(mapOver(pre), newsym, mapOverArgs(args, newsym.typeParams)) } else super.mapOver(tpe) + + case SingleType(pre, sym) => + val sym1 = updateSym(sym) + if (sym1 ne sym) { + log("fixing " + sym + " -> " + sym1) + singleType(mapOver(pre), sym1) + } else + super.mapOver(tpe) + case _ => super.mapOver(tpe) } @@ -172,7 +181,7 @@ abstract class Duplicators extends Analyzer { * namer/typer handle them, or Idents that refer to them. */ override def typed(tree: Tree, mode: Int, pt: Type): Tree = { - log("typing " + tree) + if (settings.debug.value) log("typing " + tree + ": " + tree.tpe) if (tree.hasSymbol && tree.symbol != NoSymbol && !tree.symbol.isLabel // labels cannot be retyped by the type checker as LabelDef has no ValDef/return type trees && invalidSyms.isDefinedAt(tree.symbol)) { @@ -232,7 +241,7 @@ abstract class Duplicators extends Analyzer { case This(_) if (oldClassOwner ne null) && (tree.symbol == oldClassOwner) => // val tree1 = Typed(This(newClassOwner), TypeTree(fixType(tree.tpe.widen))) val tree1 = This(newClassOwner) - log("mapped " + tree + " to " + tree1) + if (settings.debug.value) log("mapped " + tree + " to " + tree1) super.typed(atPos(tree.pos)(tree1), mode, pt) case Super(qual, mix) if (oldClassOwner ne null) && (tree.symbol == oldClassOwner) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 9ac628034f..a78ee61ee2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -384,18 +384,13 @@ trait Namers { self: Analyzer => mods &~ LOCAL } else mods // add getter and possibly also setter - val accflags: Long = ACCESSOR | - (if (mods1.isVariable) mods1.flags & ~MUTABLE & ~PRESUPER - else mods1.flags & ~PRESUPER | STABLE) if (nme.isSetterName(name)) context.error(tree.pos, "Names of vals or vars may not end in `_='") // .isInstanceOf[..]: probably for (old) IDE hook. is this obsolete? - val getter = enterAliasMethod(tree, name, accflags, mods1) + val getter = enterAccessorMethod(tree, name, getterFlags(mods1.flags), mods1) setInfo(getter)(namerOf(getter).getterTypeCompleter(vd)) if (mods1.isVariable) { - val setter = enterAliasMethod(tree, nme.getterToSetter(name), - accflags & ~STABLE & ~CASEACCESSOR, - mods1) + val setter = enterAccessorMethod(tree, nme.getterToSetter(name), setterFlags(mods1.flags), mods1) setInfo(setter)(namerOf(setter).setterTypeCompleter(vd)) } @@ -468,7 +463,7 @@ trait Namers { self: Analyzer => sym } - def enterAliasMethod(tree: Tree, name: Name, flags: Long, mods: Modifiers): TermSymbol = + def enterAccessorMethod(tree: Tree, name: Name, flags: Long, mods: Modifiers): TermSymbol = enterNewMethod(tree, name, flags, mods, tree.pos.focus) private def addBeanGetterSetter(vd: ValDef, getter: Symbol) { @@ -508,7 +503,7 @@ trait Namers { self: Analyzer => // known. instead, uses the same machinery as for the non-bean setter: // create and enter the symbol here, add the tree in Typer.addGettterSetter. val setterName = "set" + beanName - val setter = enterAliasMethod(vd, setterName, flags, mods) + val setter = enterAccessorMethod(vd, setterName, flags, mods) .setPos(vd.pos.focus) setInfo(setter)(namerOf(setter).setterTypeCompleter(vd)) } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index b5c5bc95ae..89b4f910e5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -210,8 +210,11 @@ trait NamesDefaults { self: Analyzer => blockWithoutQualifier(defaultQual) // super constructor calls - case Select(Super(_, _), _) if isConstr => - val defaultQual = moduleQual(baseFun.pos, mod => gen.mkAttributedRef(mod)) + case Select(sp @ Super(_, _), _) if isConstr => + // fix for #3207. selection of the companion module of the superclass + // needs to have the same prefix as the the superclass. + val superprefix = sp.symbol.tpe.parents.head.prefix + val defaultQual = moduleQual(baseFun.pos, mod => gen.mkAttributedRef(superprefix, mod)) blockWithoutQualifier(defaultQual) // self constructor calls (in secondary constructors) @@ -377,7 +380,8 @@ trait NamesDefaults { self: Analyzer => } else { val defGetterName = param.owner.name +"$default$"+ i if (param.owner.owner.isClass) { - param.owner.owner.info.member(defGetterName) + // .toInterface: otherwise we get the method symbol of the impl class + param.owner.owner.toInterface.info.member(defGetterName) } else { // the owner of the method is another method. find the default // getter in the context. diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 95c79eb97e..6f5175c0ea 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -182,15 +182,16 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT mayNeedProtectedAccessor(sel, args, false) case sel @ Select(qual @ This(_), name) => - if ((sym hasFlag PARAMACCESSOR) && (sym.alias != NoSymbol)) { + if ((sym hasFlag PARAMACCESSOR) + && (sym.alias != NoSymbol)) { val result = localTyper.typed { - Select( - Super(qual.symbol, nme.EMPTY.toTypeName/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos, - sym.alias) setPos tree.pos + Select( + Super(qual.symbol, nme.EMPTY.toTypeName/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos, + sym.alias) setPos tree.pos } if (settings.debug.value) Console.println("alias replacement: " + tree + " ==> " + result);//debug - transformSuperSelect(result) + localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, true)) } else mayNeedProtectedAccessor(sel, List(EmptyTree), false) diff --git a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala deleted file mode 100644 index 869c6a97e9..0000000000 --- a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala +++ /dev/null @@ -1,142 +0,0 @@ -/* NEST (New Scala Test) - * Copyright 2007-2010 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package util - -import scala.util.parsing.combinator._ -import scala.util.parsing.input.{ Reader } -import scala.util.parsing.input.CharArrayReader.EofCh -import scala.collection.mutable.ListBuffer - -/** A simple command line parser to replace the several different - * simple ones spread around trunk. - */ - -trait ParserUtil extends Parsers { - class ParserPlus[+T](underlying: Parser[T]) { - def !~>[U](p: => Parser[U]): Parser[U] = (underlying ~! p) ^^ { case a~b => b } - def <~![U](p: => Parser[U]): Parser[T] = (underlying ~! p) ^^ { case a~b => a } - } - protected implicit def parser2parserPlus[T](p: Parser[T]): ParserPlus[T] = new ParserPlus(p) -} - -case class CommandLine( - args: List[String], - unaryOptions: List[String], - binaryOptions: List[String] -) { - def this(args: List[String]) = this(args, Nil, Nil) - def this(args: Array[String]) = this(args.toList, Nil, Nil) - def this(line: String) = this(CommandLineParser tokenize line, Nil, Nil) - - def withUnary(xs: List[String]) = copy(unaryOptions = xs) - def withBinary(xs: List[String]) = copy(binaryOptions = xs) - - def allOptions = unaryOptions ++ binaryOptions - def originalArgs = args - def assumeBinary = true - def enforceArity = true - def onlyKnownOptions = false - - val Terminator = "--" - val ValueForUnaryOption = "true" // so if --opt is given, x(--opt) = true - - def mapForUnary(opt: String) = Map(opt -> ValueForUnaryOption) - def errorFn(msg: String) = println(msg) - - /** argMap is option -> argument (or "" if it is a unary argument) - * residualArgs are what is left after removing the options and their args. - */ - lazy val (argMap, residualArgs) = { - val residualBuffer = new ListBuffer[String] - - def stripQuotes(s: String) = { - def isQuotedBy(c: Char) = s.length > 0 && s.head == c && s.last == c - if (List('"', '\'') exists isQuotedBy) s.tail.init else s - } - - def isValidOption(s: String) = !onlyKnownOptions || (unaryOptions contains s) || (binaryOptions contains s) - def isOption(s: String) = (s startsWith "-") && (isValidOption(s) || { unknownOption(s) ; false }) - def isUnary(s: String) = isOption(s) && (unaryOptions contains s) - def isBinary(s: String) = isOption(s) && !isUnary(s) && (assumeBinary || (binaryOptions contains s)) - - def unknownOption(opt: String) = - errorFn("Option '%s' not recognized.".format(opt)) - def missingArg(opt: String, what: String) = - errorFn("Option '%s' requires argument, found %s instead.".format(opt, what)) - - def loop(args: List[String]): Map[String, String] = { - def residual(xs: List[String]) = { residualBuffer ++= xs ; Map[String, String]() } - if (args.isEmpty) return Map() - val hd :: rest = args - if (rest.isEmpty) { - if (isBinary(hd) && enforceArity) - missingArg(hd, "EOF") - - if (isOption(hd)) mapForUnary(hd) else residual(args) - } - else - if (hd == Terminator) residual(rest) - else { - val hd1 :: hd2 :: rest = args - - if (hd2 == Terminator) mapForUnary(hd1) ++ residual(rest) - else if (isUnary(hd1)) mapForUnary(hd1) ++ loop(hd2 :: rest) - else if (isBinary(hd1)) { - // Disabling this check so - // --scalacopts "-verbose" works. We can't tell if it's quoted, - // the shell does us in. - // - // if (isOption(hd2) && enforceArity) - // missingArg(hd1, hd2) - - Map(hd1 -> hd2) ++ loop(rest) - } - else { residual(List(hd1)) ++ loop(hd2 :: rest) } - } - } - - (loop(args), residualBuffer map stripQuotes toList) - } - - def isSet(arg: String) = args contains arg - def get(arg: String) = argMap get arg - def getOrElse(arg: String, orElse: => String) = if (isSet(arg)) apply(arg) else orElse - def apply(arg: String) = argMap(arg) - - override def toString() = "CommandLine(\n%s)\n" format (args map (" " + _ + "\n") mkString) -} - -object CommandLineParser extends RegexParsers with ParserUtil { - override def skipWhitespace = false - - def elemExcept(xs: Elem*): Parser[Elem] = elem("elemExcept", x => x != EofCh && !(xs contains x)) - def elemOf(xs: Elem*): Parser[Elem] = elem("elemOf", xs contains _) - def escaped(ch: Char): Parser[String] = "\\" + ch - def mkQuoted(ch: Char): Parser[String] = ( - elem(ch) !~> rep(escaped(ch) | elemExcept(ch)) <~ ch ^^ (_.mkString) - | failure("Unmatched %s in input." format ch) - ) - - /** Apparently windows can't deal with the quotes sticking around. */ - lazy val squoted: Parser[String] = mkQuoted('\'') // ^^ (x => "'%s'" format x) - lazy val dquoted: Parser[String] = mkQuoted('"') // ^^ (x => "\"" + x + "\"") - lazy val token: Parser[String] = """\S+""".r - - lazy val argument: Parser[String] = squoted | dquoted | token - lazy val commandLine: Parser[List[String]] = phrase(repsep(argument, whiteSpace)) - - class ParseException(msg: String) extends RuntimeException(msg) - - def tokenize(line: String): List[String] = tokenize(line, x => throw new ParseException(x)) - def tokenize(line: String, errorFn: String => Unit): List[String] = { - parse(commandLine, line.trim) match { - case Success(args, _) => args - case NoSuccess(msg, rest) => errorFn(msg) ; Nil - } - } - def apply(line: String) = new CommandLine(tokenize(line)) -} diff --git a/src/compiler/scala/tools/nsc/util/CommandLineSpec.scala b/src/compiler/scala/tools/nsc/util/CommandLineSpec.scala deleted file mode 100644 index 826255e86f..0000000000 --- a/src/compiler/scala/tools/nsc/util/CommandLineSpec.scala +++ /dev/null @@ -1,150 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2010 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package util - -import Properties._ -import io._ -import CommandLineSpec._ -import CommandLineParser.tokenize - -/** This trait works together with CommandLine to allow declaratively - * specifying a command line program, with many attendant benefits. - * See scala.tools.partest.PartestSpec for a full example. - */ - -trait CommandLineSpec { - def parsed: CommandLine - def isReferenceSpec: Boolean = false - def isPassthroughProperty(name: String): Boolean = false - def isSysPropOption(key: String): Option[String] = None - - protected var _expandingOptions: Map[String, List[String]] = Map() - - private var _helpMessage: String = "" - private var _unaryOptions: List[String] = Nil - private var _binaryOptions: List[String] = Nil - private def allOptions = if (isReferenceSpec) Nil else parsed.allOptions - private def longestArg = if (allOptions.isEmpty) 1 else allOptions map (_.length) max - private def unquoted(s: String) = { - def isQuoted = (s.head == '\'' || s.head == '"') && s.head == s.last - - if (s == null || s.length < 2 || !isQuoted) s - else s drop 1 dropRight 1 - } - - protected def help(str: String) = if (isReferenceSpec) () else _helpMessage += (str.stripMargin + "\n") - protected def heading(s: String) = if (isReferenceSpec) () else help("\n " + s) - - /** The various operators: - * val isCond1 = "cond1" ? // --cond1 is unary, cond1 is boolean - * "cond2" ?> body // --cond2 is unary, body is executed if it is given - * "cond3" ?+> List(x1, x2...) // --cond3 is unary, arguments on rhs will be substituted in as if given - * val val1 = "val1" |> "alt" // --val1 is binary, val1 is String, alt used if none given - * val val2 = "val2" >> // --val2 is binary, val2 is Option[String], None if none given - */ - protected class OptionStringAdditions(name: String) { - val s = toOpt(name) - def ?+>(args: List[String]): Unit = { _unaryOptions +:= s ; if (isReferenceSpec) _expandingOptions += (name -> args) } - - def ? : Boolean = { _unaryOptions +:= s ; if (isReferenceSpec) false else parsed isSet s } - def ?>(body: => Unit): Unit = { _unaryOptions +:= s ; if (isReferenceSpec) () else if (parsed isSet s) body } - def |>(alt: String): String = { _binaryOptions +:= s ; if (isReferenceSpec) "" else parsed.getOrElse(s, alt) } - def >> : Option[String] = { _binaryOptions +:= s ; if (isReferenceSpec) None else parsed get s } - - def /(description: String) = { - val formatStr = " %-" + longestArg + "s %s" - help(formatStr.format(s, description)) - - name - } - } - protected implicit def stringAdditions(s: String) = new OptionStringAdditions(s) - - lazy val unaryOptions = _unaryOptions.distinct - lazy val binaryOptions = _binaryOptions.distinct - lazy val expandingOptions = _expandingOptions.keys.toList - lazy val helpMsg = _helpMessage - - def isUnaryOption(s: String) = unaryOptions contains toOpt(s) - def isBinaryOption(s: String) = binaryOptions contains toOpt(s) - def isExpandingOption(s: String) = expandingOptions contains toOpt(s) - - private def sysPropToOptions(k: String, v: String): List[String] = { - if (isPassthroughProperty(k)) toArgs(v) - else isSysPropOption(k).toList flatMap { optName => - val opt = toOpt(optName) - - if (isUnaryOption(optName)) List(opt) - else if (isBinaryOption(optName)) List(opt, v) - else { - if (warnSuspiciousProperties) { - println("Warning, this looks like a command line option but I don't understand it.") - println("Ignoring: " + k + "=" + v) - } - Nil - } - } - } - def warnSuspiciousProperties: Boolean = true - def sysPropsAsOptions() = allSystemProperties.toList flatMap (sysPropToOptions _).tupled - - def isSet(s: String) = parsed isSet toOpt(s) - def reconstruct: List[String] = { - val unary = unaryOptions filter (parsed isSet _) - val binary = binaryOptions collect { case x if parsed isSet x => List(x, parsed(x)) } - val resid = parsed.residualArgs - - unary ++ binary.flatten ++ resid - } - - def bashCompletion(programName: String) = { - val opts = unaryOptions ++ binaryOptions - bashCompletionTemplate.replaceAll("@@PROGRAM@@", programName).replaceAll("@@OPTIONS@@", opts mkString " ") - } -} - -trait CommandLineReferenceSpec extends CommandLineSpec { - final override def isReferenceSpec: Boolean = true - final def apply(args: String*) = creator(args.toList flatMap expandArg) - - protected lazy val expansionMap = _expandingOptions - protected def creator(args: List[String]) = new ThisCommandLine(args) - protected def expandArg(arg: String) = expansionMap.getOrElse(fromOpt(arg), List(arg)) - - class ThisCommandLine(args: List[String]) extends CommandLine(args, unaryOptions, binaryOptions) { - } -} - -object CommandLineSpec { - def toOpt(s: String) = if (s startsWith "--") s else "--" + s - def fromOpt(s: String) = s stripPrefix "--" - def toArgs(line: String) = tokenize(line) - def fromArgs(args: List[String]) = args mkString " " - - def allSystemProperties: Map[String, String] = { - import collection.JavaConversions._ - - System.getProperties.toMap - } - - /** A very simple template for generating bash completion functions. - */ - val bashCompletionTemplate = """ - |_@@PROGRAM@@() - |{ - | local cur opts base - | COMPREPLY=() - | cur="${COMP_WORDS[COMP_CWORD]}" - | opts="@@OPTIONS@@" - | - | COMPREPLY=($(compgen -W "${opts}" -- ${cur})) - | _filedir - | return 0 - |} - |complete -F _@@PROGRAM@@ @@PROGRAM@@ - """.stripMargin -} diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala index 197eb28661..740e42192b 100644 --- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala +++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala @@ -4,7 +4,8 @@ */ // $Id$ -package scala.tools.nsc +package scala.tools +package nsc package util import java.io.{File, FileInputStream, PrintStream, IOException} @@ -290,7 +291,7 @@ object ShowPickled extends Names { /** Option --bare suppresses numbers so the output can be diffed. */ def main(args: Array[String]) { - val parsed = CommandLine(args.toList, List("--bare"), Nil) + val parsed = cmd.CommandLine(args.toList, List("--bare"), Nil) def isBare = parsed isSet "--bare" parsed.residualArgs foreach { arg => diff --git a/src/compiler/scala/tools/util/BashCompletion.scala b/src/compiler/scala/tools/util/BashCompletion.scala deleted file mode 100644 index ed9f1b505a..0000000000 --- a/src/compiler/scala/tools/util/BashCompletion.scala +++ /dev/null @@ -1,132 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2006-2010 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools -package util - -import nsc.{ Global, Settings } - -/** Examines Settings and generates a bash completion file - * containing both bells and whistles. - */ -object BashCompletion { - val completionTemplate = """ -# Bash Scala completion -# -# Add this file to /etc/bash_completion.d/ (or your local equivalent) -# or place a line like this in your .bashrc or .profile: -# -# . /path/to/file/scala_completion.sh -# -# For more information, see: -# -# http://bash-completion.alioth.debian.org/ -# -# This file is generated by running scala.tools.util.BashCompletion. -# - -SCALA_PHASES="@@PHASES@@" -SCALA_PHASE_SETTINGS=( @@PHASE_SETTINGS@@ ) -SCALA_OPTIONS="@@OPTIONS@@" -SCALA_OPTIONS_EXPANDED="@@OPTIONS_EXPANDED@@" - -_scala_completion() -{ - local cur prev opts colonprefixes - - COMPREPLY=() - opts="" - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - colonprefixes=${cur%"${cur##*:}"} - - # special case escaping madness because bash treats : as a separator. - case "${cur}" in - -*:*) - precolon=$(echo "${cur}" | sed 's/:.*//g') - - for p in ${SCALA_PHASE_SETTINGS[@]}; do - if [[ "${precolon}" == "${p}" ]] ; then - cur=$(echo "${cur}" | sed 's/.*://g') # cut cur down to postcolon part - opts=${SCALA_PHASES} - fi - done - - if [ "${opts}" == "" ] ; then - opts=${SCALA_OPTIONS_EXPANDED} - fi - ;; - esac - - if [ "${opts}" == "" ] ; then - opts=${SCALA_OPTIONS} - fi - - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - - local i=${#COMPREPLY[*]} - while [ $((--i)) -ge 0 ]; do - COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"} - done - - return 0 -} - -_scala_commands() -{ -@@PROGRAMS@@ -} -_scala_commands - """.trim - - private lazy val settings = new Settings() - import settings._ - - val phaseNames = "all" :: (new Global(settings) phaseNames) - val phaseSettings = settings.visibleSettings collect { case x: PhasesSetting => "\"" + x.name + "\"" } - - def settingStrings(s: Setting, expanded: Boolean) = s match { - case x: ChoiceSetting => if (expanded) x.choices map (x.name + ":" + _) else List(x.name + ":") - case x: PhasesSetting => List(x.name + ":") - case x => List(x.name) - } - - /** We embed one list which stops at : and another where all choice settings are expanded out - * to include the choices. - */ - def settingNames = settings.visibleSettings.toList flatMap (x => settingStrings(x, false)) sorted - def settingNamesExpanded = settings.visibleSettings.toList flatMap (x => settingStrings(x, true)) sorted - - def commandForName(name: String) = " complete -o default -F _scala_completion " + name + "\n" - def interpolate(template: String, what: (String, String)*) = - what.foldLeft(template) { - case (text, (key, value)) => - val token = "@@" + key + "@@" - - (text indexOf token) match { - case -1 => error("Token '%s' does not exist." format token) - case idx => (text take idx) + value + (text drop idx drop token.length) - } - } - - def create(cmds: List[String]) = { - interpolate(completionTemplate, - "PROGRAMS" -> (cmds map commandForName mkString ""), - "OPTIONS" -> (settingNames mkString " "), - "OPTIONS_EXPANDED" -> (settingNamesExpanded mkString " "), - "PHASES" -> (phaseNames mkString " "), - "PHASE_SETTINGS" -> (phaseSettings mkString " ") - ) - } - - def main(args: Array[String]): Unit = { - val commands = if (args.isEmpty) List("fsc", "scala", "scalac", "scaladoc") else args.toList - val result = create(commands) - if (result contains "@@") - error("Some tokens were not replaced: text is " + result) - - println(result) - } -}
\ No newline at end of file diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala index 716b0b43dc..d2cb5e74c0 100644 --- a/src/compiler/scala/tools/util/PathResolver.scala +++ b/src/compiler/scala/tools/util/PathResolver.scala @@ -119,9 +119,9 @@ object PathResolver { case _ => "" } - def scalaExtDirs = Environment.scalaExtDirs - def scalaPluginDirs = List("misc", "scala-devel", "plugins") - def scalaPluginPath = join(scalaPluginDirs map (scalaHomeDir / _ path): _*) + def scalaExtDirs = Environment.scalaExtDirs + + def scalaPluginPath = (scalaHomeDir / "misc" / "scala-devel" / "plugins").path override def toString = """ |object Defaults { diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index 0525e6fdbc..936b572caf 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -211,12 +211,12 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with case ldef @ LabelDef(name, params, rhs) => if (hasAnswerTypeAnn(tree.tpe)) { - val sym = currentOwner.newMethod(tree.pos, name)//unit.fresh.newName(tree.pos, "myloopvar")) + val sym = currentOwner.newMethod(tree.pos, name)//unit.fresh.newName(tree.pos, "myloopvar") .setInfo(ldef.symbol.info) .setFlag(Flags.SYNTHETIC) - new TreeSymSubstituter(List(ldef.symbol), List(sym)).traverse(rhs) - val rhsVal = transExpr(rhs, None, getAnswerTypeAnn(tree.tpe)) + val rhs1 = new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs) + val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe)) val stm1 = localTyper.typed(DefDef(sym, rhsVal)) val expr = localTyper.typed(Apply(Ident(sym), List())) diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala index 6da56f93d4..07a9e5fed5 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala @@ -288,9 +288,9 @@ abstract class SelectiveCPSTransform extends PluginComponent with def applyTrivial(ctxValSym: Symbol, body: Tree) = { - new TreeSymSubstituter(List(vd.symbol), List(ctxValSym)).traverse(body) + val body1 = (new TreeSymSubstituter(List(vd.symbol), List(ctxValSym)))(body) - val body2 = localTyper.typed(atPos(vd.symbol.pos) { body }) + val body2 = localTyper.typed(atPos(vd.symbol.pos) { body1 }) // in theory it would be nicer to look for an @cps annotation instead // of testing for Context @@ -303,10 +303,10 @@ abstract class SelectiveCPSTransform extends PluginComponent with def applyCombinatorFun(ctxR: Tree, body: Tree) = { val arg = currentOwner.newValueParameter(ctxR.pos, name).setInfo(tpe) - new TreeSymSubstituter(List(vd.symbol), List(arg)).traverse(body) - val fun = localTyper.typed(atPos(vd.symbol.pos) { Function(List(ValDef(arg)), body) }) // types body as well + val body1 = (new TreeSymSubstituter(List(vd.symbol), List(arg)))(body) + val fun = localTyper.typed(atPos(vd.symbol.pos) { Function(List(ValDef(arg)), body1) }) // types body as well arg.owner = fun.symbol - new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(body) + new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(body1) // see note about multiple traversals above @@ -315,12 +315,12 @@ abstract class SelectiveCPSTransform extends PluginComponent with log("arg.owner: "+arg.owner) log("fun.tpe:"+fun.tpe) - log("return type of fun:"+body.tpe) + log("return type of fun:"+body1.tpe) var methodName = "map" - if (body.tpe != null) { - if (body.tpe.typeSymbol == Context) + if (body1.tpe != null) { + if (body1.tpe.typeSymbol == Context) methodName = "flatMap" } else diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index 75110d7d4e..afc19417a2 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -35,7 +35,7 @@ package scala * println(anonfun1(0)) * }</pre> */ -trait Function1[-T1, +R] extends AnyRef { self => +trait Function1[@specialized(Int, Long, Double) -T1, @specialized(Unit, Int, Long, Double) +R] extends AnyRef { self => def apply(v1:T1): R override def toString() = "<function1>" diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index 99c4ed1d2a..46023a9b3b 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -35,7 +35,9 @@ package scala * println(anonfun2(0, 1)) * }</pre> */ -trait Function2[-T1, -T2, +R] extends AnyRef { self => +trait Function2[@specialized(Int, Long, Double) -T1, + @specialized(Int, Long, Double) -T2, + @specialized(Unit, Int, Long, Double) +R] extends AnyRef { self => def apply(v1:T1,v2:T2): R override def toString() = "<function2>" diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala index 2cca5fe7d5..0e93065e5a 100644 --- a/src/library/scala/Product1.scala +++ b/src/library/scala/Product1.scala @@ -22,7 +22,7 @@ object Product1 { * * @since 2.3 */ -trait Product1[+T1] extends Product { +trait Product1[@specialized(Int, Long, Double) +T1] extends Product { /** * The arity of this product. * @return 1 diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala index 27580f8658..436de41a01 100644 --- a/src/library/scala/Product2.scala +++ b/src/library/scala/Product2.scala @@ -22,7 +22,8 @@ object Product2 { * * @since 2.3 */ -trait Product2[+T1, +T2] extends Product { +trait Product2[@specialized(Int, Long, Double) +T1, + @specialized(Int, Long, Double) +T2] extends Product { /** * The arity of this product. * @return 2 diff --git a/src/library/scala/Tuple1.scala b/src/library/scala/Tuple1.scala index d57c58fe78..5d25cc5abb 100644 --- a/src/library/scala/Tuple1.scala +++ b/src/library/scala/Tuple1.scala @@ -17,7 +17,7 @@ package scala /** Tuple1 is the canonical representation of a @see Product1 * */ -case class Tuple1[+T1](_1:T1) +case class Tuple1[@specialized(Int, Long, Double) +T1](_1:T1) extends Product1[T1] { override def toString() = "(" + _1 + ")" diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 8c4e5973c5..7fea22410d 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -19,7 +19,8 @@ import scala.collection.generic.CanBuildFrom /** Tuple2 is the canonical representation of a @see Product2 * */ -case class Tuple2[+T1, +T2](_1:T1,_2:T2) +case class Tuple2[@specialized(Int, Long, Double) +T1, + @specialized(Int, Long, Double) +T2](_1:T1,_2:T2) extends Product2[T1, T2] { override def toString() = "(" + _1 + "," + _2 + ")" diff --git a/src/library/scala/collection/BitSet.scala b/src/library/scala/collection/BitSet.scala index abb4856bcd..b43b681888 100644 --- a/src/library/scala/collection/BitSet.scala +++ b/src/library/scala/collection/BitSet.scala @@ -15,17 +15,16 @@ import generic._ /** A common base class for mutable and immutable bitsets. * $bitsetinfo - - * @author Martin Odersky - * @version 2.8 - * @since 1 */ trait BitSet extends Set[Int] with BitSetLike[BitSet] { override def empty: BitSet = BitSet.empty } -/** $factoryInfo */ +/** $factoryInfo + * @define coll bitset + * @define Coll BitSet + */ object BitSet extends BitSetFactory[BitSet] { val empty: BitSet = immutable.BitSet.empty /** $canBuildFromInfo */ diff --git a/src/library/scala/collection/BitSetLike.scala b/src/library/scala/collection/BitSetLike.scala index 8476ede7b5..7c5e2fb269 100644 --- a/src/library/scala/collection/BitSetLike.scala +++ b/src/library/scala/collection/BitSetLike.scala @@ -21,17 +21,17 @@ import mutable.StringBuilder * This trait provides most of the operations of a `BitSet` independently of its representation. * It is inherited by all concrete implementations of bitsets. * - * @tparam This the type of the bitset itself. + * @tparam This the type of the bitset itself. * + * @define bitsetinfo + * Bitsets are sets of non-negative integers which are represented as + * variable-size arrays of bits packed into 64-bit words. The size of a bitset is + * determined by the largest number stored in it. * @author Martin Odersky * @version 2.8 * @since 2.8 * @define coll bitset * @define Coll BitSet - * @define bitsetinfo - * Bitsets are sets of non-negative integers which are represented as - * variable-size arrays of bits packed into 64-bit words. The size of a bitset is - * determined by the largest number stored in it. */ trait BitSetLike[+This <: BitSetLike[This] with Set[Int]] extends SetLike[Int, This] { self => diff --git a/src/library/scala/collection/IndexedSeq.scala b/src/library/scala/collection/IndexedSeq.scala index 50a66e924c..72878a8ad6 100644 --- a/src/library/scala/collection/IndexedSeq.scala +++ b/src/library/scala/collection/IndexedSeq.scala @@ -16,10 +16,6 @@ import mutable.Builder /** A base trait for indexed sequences. * $indexedSeqInfo - * - * @author Martin Odersky - * @version 2.8 - * @since 2.8 */ trait IndexedSeq[+A] extends Seq[A] with GenericTraversableTemplate[A, IndexedSeq] @@ -27,6 +23,10 @@ trait IndexedSeq[+A] extends Seq[A] override def companion: GenericCompanion[IndexedSeq] = IndexedSeq } +/** $factoryInfo + * @define coll indexed sequence + * @define Coll IndexedSeq + */ object IndexedSeq extends SeqFactory[IndexedSeq] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, IndexedSeq[A]] = new GenericCanBuildFrom[A] def newBuilder[A]: Builder[A, IndexedSeq[A]] = immutable.IndexedSeq.newBuilder[A] diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala index ea6e1bb493..453b4384f7 100644 --- a/src/library/scala/collection/IndexedSeqLike.scala +++ b/src/library/scala/collection/IndexedSeqLike.scala @@ -23,21 +23,20 @@ import scala.annotation.tailrec * However, see `IndexedSeqOptimized` for an implementation trait that overrides operations * to make them run faster under the assumption of fast random access with `apply`. * - * @author Sean McDirmid - * @author Martin Odersky - * @version 2.8 - * @since 2.8 * @define Coll IndexedSeq * @define indexedSeqInfo * Indexed sequences support constant-time or near constant-time element * access and length computation. They are defined in terms of abstract methods - * `apply` fpor indexing and `length`. + * `apply` for indexing and `length`. * * Indexed sequences do not add any new methods wrt `Seq`, but promise * efficient implementations of random access patterns. * * @tparam A the element type of the $coll * @tparam Repr the type of the actual $coll containing the elements. + * @author Martin Odersky + * @version 2.8 + * @since 2.8 * @define willNotTerminateInf * @define mayNotTerminateInf */ diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala index 12b39c8b83..9702297a57 100755 --- a/src/library/scala/collection/IndexedSeqOptimized.scala +++ b/src/library/scala/collection/IndexedSeqOptimized.scala @@ -19,12 +19,7 @@ import scala.annotation.tailrec * the implementation of several methods under the assumption of fast random access. * * $indexedSeqInfo - * @author Martin Odersky - * @version 2.8 - * @since 2.8 * - * @tparam A the element type of the $coll - * @tparam Repr the type of the actual $coll containing the elements. * @define willNotTerminateInf * @define mayNotTerminateInf */ diff --git a/src/library/scala/collection/Iterable.scala b/src/library/scala/collection/Iterable.scala index ba5eb4c0a0..65d4dfcbe2 100644 --- a/src/library/scala/collection/Iterable.scala +++ b/src/library/scala/collection/Iterable.scala @@ -15,7 +15,8 @@ import generic._ import scala.util.control.Breaks._ import mutable.Builder -/** $iterableInfo +/** A base trait for iterable collections. + * $iterableInfo */ trait Iterable[+A] extends Traversable[A] with GenericTraversableTemplate[A, Iterable] @@ -35,6 +36,8 @@ trait Iterable[+A] extends Traversable[A] } /** $factoryInfo + * @define coll iterable collection + * @define Coll Iterable */ object Iterable extends TraversableFactory[Iterable] { diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index e348ba12e5..0efc756b10 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -15,10 +15,8 @@ import annotation.unchecked.uncheckedVariance /** A template trait for iterable collections of type `Iterable[A]`. * $iterableInfo - * @tparam A the element type of the collection - * @tparam Repr the type of the actual collection containing the elements. * @define iterableInfo - * This is a base trait for all scala collections that define an `iterator` + * This is a base trait for all $mutability Scala collections that define an `iterator` * method to step through one-by-one the collection's elements. * Implementations of this trait need to provide a concrete method with * signature: @@ -44,6 +42,8 @@ import annotation.unchecked.uncheckedVariance * @author Martin Odersky * @version 2.8 * @since 2.8 + * @tparam A the element type of the collection + * @tparam Repr the type of the actual collection containing the elements. * * @define Coll Iterable * @define coll iterable collection diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala index 09f084d92c..b8f0b65faf 100644 --- a/src/library/scala/collection/IterableViewLike.scala +++ b/src/library/scala/collection/IterableViewLike.scala @@ -15,11 +15,19 @@ import generic._ import collection.immutable.Stream import TraversableView.NoBuilder -/** A template trait for a non-strict view of an iterable. +/** A template trait for non-strict views of iterable collections. + * $iterableviewInfo + * + * @define iterableviewInfo + * $viewinfo + * All views for iterable collections are defined by creating a new `iterator` method. * * @author Martin Odersky * @version 2.8 * @since 2.8 + * @tparam A the element type of the view + * @tparam Coll the type of the underlying collection containing the elements. + * @tparam This the type of the view itself */ trait IterableViewLike[+A, +Coll, diff --git a/src/library/scala/collection/LinearSeq.scala b/src/library/scala/collection/LinearSeq.scala index 1afb2fdb7f..ef7d4c9390 100644 --- a/src/library/scala/collection/LinearSeq.scala +++ b/src/library/scala/collection/LinearSeq.scala @@ -16,9 +16,6 @@ import mutable.Builder /** A base trait for linear sequences. * $linearSeqInfo - * - * @author Martin Odersky - * @since 2.8 */ trait LinearSeq[+A] extends Seq[A] with GenericTraversableTemplate[A, LinearSeq] @@ -26,8 +23,9 @@ trait LinearSeq[+A] extends Seq[A] override def companion: GenericCompanion[LinearSeq] = LinearSeq } -/** - * @since 2.8 +/** $factoryInfo + * @define coll linear sequence + * @define Coll LinearSeq */ object LinearSeq extends SeqFactory[LinearSeq] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, LinearSeq[A]] = new GenericCanBuildFrom[A] diff --git a/src/library/scala/collection/LinearSeqLike.scala b/src/library/scala/collection/LinearSeqLike.scala index 1c99d4a3d9..208cbcdd50 100644 --- a/src/library/scala/collection/LinearSeqLike.scala +++ b/src/library/scala/collection/LinearSeqLike.scala @@ -25,10 +25,6 @@ import scala.util.control.Breaks._ * However, see `LinearSeqOptimized` for an implementation trait that overrides operations * to make them run faster under the assumption of fast linear access with `head` and `tail`. * - * @author Martin Odersky - * @version 2.8 - * @since 2.8 - * * @define linearSeqInfo * Linear sequences are defined in terms of three abstract methods, which are assumed * to have efficient implementations. These are: @@ -41,6 +37,9 @@ import scala.util.control.Breaks._ * * Linear sequences do not add any new methods to `Seq`, but promise efficient implementations * of linear access patterns. + * @author Martin Odersky + * @version 2.8 + * @since 2.8 * * @tparam A the element type of the $coll * @tparam Repr the type of the actual $coll containing the elements. diff --git a/src/library/scala/collection/LinearSeqOptimized.scala b/src/library/scala/collection/LinearSeqOptimized.scala index 7d3c58ad85..2add28d7c3 100755 --- a/src/library/scala/collection/LinearSeqOptimized.scala +++ b/src/library/scala/collection/LinearSeqOptimized.scala @@ -20,12 +20,6 @@ import scala.util.control.Breaks._ * the implementation of several methods under the assumption of fast linear access. * * $linearSeqInfo - * @author Martin Odersky - * @version 2.8 - * @since 2.8 - * - * @tparam A the element type of the $coll - * @tparam Repr the type of the actual $coll containing the elements. */ trait LinearSeqOptimized[+A, +Repr <: LinearSeqOptimized[A, Repr]] extends LinearSeqLike[A, Repr] { self: Repr => diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala index 6a9fffe3e1..057224a705 100644 --- a/src/library/scala/collection/MapLike.scala +++ b/src/library/scala/collection/MapLike.scala @@ -233,13 +233,10 @@ self => } /** Transforms this map by applying a function to every retrieved value. - * @param d the function used to transform values of this map. - * @return an immutable map which maps every key of this map + * @param f the function used to transform values of this map. + * @return a map view which maps every key of this map * to `f(this(key))`. The resulting map wraps the original map without copying any elements. */ - /** A map view resulting from applying a given function `f` to each value - * associated with a key in this map. - */ def mapValues[C](f: B => C): Map[A, C] = new DefaultMap[A, C] { override def foreach[D](g: ((A, C)) => D): Unit = for ((k, v) <- self) g((k, f(v))) def iterator = for ((k, v) <- self.iterator) yield (k, f(v)) diff --git a/src/library/scala/collection/Seq.scala b/src/library/scala/collection/Seq.scala index 1fac25d00d..baf2c0031e 100644 --- a/src/library/scala/collection/Seq.scala +++ b/src/library/scala/collection/Seq.scala @@ -16,7 +16,6 @@ import mutable.Builder /** A base trait for sequences. * $seqInfo - * @tparam A the element type of the $coll */ trait Seq[+A] extends PartialFunction[Int, A] with Iterable[A] @@ -25,7 +24,10 @@ trait Seq[+A] extends PartialFunction[Int, A] override def companion: GenericCompanion[Seq] = Seq } -/** $factoryInfo */ +/** $factoryInfo + * @define coll sequence + * @define Coll Seq + */ object Seq extends SeqFactory[Seq] { private[collection] val hashSeed = "Seq".hashCode diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index c35039c520..b9ac28cb2d 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -99,13 +99,9 @@ object SeqLike { } } -/** A template trait for sequences of type `Seq[A]`, representing - * sequences of elements of type <code>A</code>. +/** A template trait for sequences of type `Seq[A]` * $seqInfo * - * @tparam A the element type of the collection - * @tparam Repr the type of the actual collection containing the elements. - * * @define seqInfo * Sequences are special cases of iterable collections of class `Iterable`. * Unlike iterables, sequences always have a defined order of elements. @@ -121,11 +117,14 @@ object SeqLike { * Sequences can be accessed in reverse order of their elements, using methods * `reverse` and `reverseIterator`. * - * Sequences have two principle subtraits, `IndexedSeq` and `LinearSeq`, which give different guarantees for performance. + * Sequences have two principal subtraits, `IndexedSeq` and `LinearSeq`, which give different guarantees for performance. * An `IndexedSeq` provides fast random-access of elements and a fast `length` operation. * A `LinearSeq` provides fast access only to the first element via `head`, but also * has a fast `tail` operation. * + * @tparam A the element type of the collection + * @tparam Repr the type of the actual collection containing the elements. + * * @author Martin Odersky * @author Matthias Zenger * @version 1.0, 16/07/2003 diff --git a/src/library/scala/collection/SeqView.scala b/src/library/scala/collection/SeqView.scala index 79d50f1de6..9a0025bd81 100644 --- a/src/library/scala/collection/SeqView.scala +++ b/src/library/scala/collection/SeqView.scala @@ -22,6 +22,8 @@ import TraversableView.NoBuilder trait SeqView[+A, +Coll] extends SeqViewLike[A, Coll, SeqView[A, Coll]] /** $factoryInfo + * @define coll sequence view + * @define Coll SeqView */ object SeqView { type Coll = TraversableView[_, C] forSome {type C <: Traversable[_]} diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index 1cecec5227..4a1cd01af1 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -15,10 +15,8 @@ import generic._ import mutable.{Builder, Buffer, ArrayBuffer, ListBuffer} import scala.util.control.Breaks -/** A template trait for traversable collections. - * $traversableinfo - * - * @tparam A The element type of the collection +/** A trait for traversable collections. + * $traversableInfo */ trait Traversable[+A] extends TraversableLike[A, Traversable[A]] with GenericTraversableTemplate[A, Traversable] { @@ -84,7 +82,8 @@ trait Traversable[+A] extends TraversableLike[A, Traversable[A]] */ } -/** $factoryInfo */ +/** $factoryInfo + */ object Traversable extends TraversableFactory[Traversable] { self => /** Provides break functionality separate from client code */ diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index c5db41005e..4c8d34622e 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -17,18 +17,15 @@ import mutable.{Builder, StringBuilder, Buffer, ArrayBuffer, ListBuffer} import immutable.{List, Stream, Nil, ::} /** A template trait for traversable collections of type `Traversable[A]`. - * $traversableinfo - * - * @tparam A the element type of the collection - * @tparam Repr the type of the actual collection containing the elements. - * - * @define traversableinfo - * This is a base trait of all kinds of Scala collections. It implements + * $traversableInfo + * @define mutability + * @define traversableInfo + * This is a base trait of all kinds of $mutability Scala collections. It implements * the behavior common to all collections, in terms of a method * `foreach` with signature: - * {{{ - * def foreach[U](f: Elem => U): Unit</pre> - * }}} + * {{{ + * def foreach[U](f: Elem => U): Unit + * }}} * Collection classes mixing in this trait provide a concrete * `foreach` method which traverses all the * elements contained in the collection, applying a given function to each. @@ -63,7 +60,9 @@ import immutable.{List, Stream, Nil, ::} * @author Martin Odersky * @version 2.8 * @since 2.8 - + * @tparam A the element type of the collection + * @tparam Repr the type of the actual collection containing the elements. + * * @define Coll Traversable * @define coll traversable collection * @define thatinfo the class of the returned collection. Where possible, `That` is @@ -178,10 +177,10 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] with Traversable * @return a new $coll which contains all elements of this $coll * followed by all elements of `that`. */ - def ++[B >: A, That](xs: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { + def ++[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) b ++= thisCollection - b ++= xs + b ++= that b.result } diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index ad3a8c6198..54efa62ef3 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -10,8 +10,8 @@ package scala.collection import mutable.{ Buffer, ListBuffer, ArrayBuffer } -/** A template trait for collections which can be traversed one - * or more times. +/** A template trait for collections which can be traversed either once only + * or one or more times. * $traversableonceinfo * * @tparam A the element type of the collection diff --git a/src/library/scala/collection/TraversableView.scala b/src/library/scala/collection/TraversableView.scala index e9332097e7..ccc33a495d 100644 --- a/src/library/scala/collection/TraversableView.scala +++ b/src/library/scala/collection/TraversableView.scala @@ -15,15 +15,7 @@ import generic._ import mutable.Builder import TraversableView.NoBuilder -/** <p> - * A base class for views of <a href="../Traversable.html" - * target="ContentFrame"><code>Traversable<code></a>.<br/> - * Every subclass has to implement the <code>foreach</code> method. - * </p> - * - * @author Martin Odersky - * @version 2.8 - * @since 2.8 +/** $traversableviewinfo */ trait TraversableView[+A, +Coll] extends TraversableViewLike[A, Coll, TraversableView[A, Coll]] diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index 09e6a65158..96fc55497d 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -15,20 +15,32 @@ import generic._ import mutable.{Builder, ArrayBuffer} import TraversableView.NoBuilder -/** <p> - * A template trait for views of <a href="../Traversable.html" - * target="contentFrame"><code>Traversable</code></a>.<br/> - * Every subclass has to implement the <code>foreach</code> method. - * </p> - * @note Methods such as map/flatMap on this will not invoke the implicitly passed - * Builder factory, but will return a new view directly, to preserve by-name behavior. - * The new view is then cast to the factory's result type. - * This means that every CanBuildFrom that takes a - * View as its From type parameter must yield the same view (or a generic superclass of it) - * as its result parameter. If that assumption is broken, cast errors might result. +/** A template trait for non-strict views of traversable collections. + * $traversableviewinfo * + * Implementation note: Methods such as `map` or `flatMap` on this view will not invoke the implicitly passed + * `Builder` factory, but will return a new view directly, to preserve by-name behavior. + * The new view is then cast to the factory's result type. This means that every `CanBuildFrom` + * that takes a `View` as its `From` type parameter must yield the same view (or a generic + * superclass of it) as its result parameter. If that assumption is broken, cast errors might result. + * + * @define viewinfo + * A view is a lazy version of some collection. Collection transformers such as + * `map` or `filter` or `++` do not traverse any elements when applied on a view. + * Instead they create a new view which simply records that fact that the operation + * needs to be applied. The collection elements are accessed, and the view operations are applied, + * when a non-view result is needed, or when the `force` method is called on a view. + * @define traversableviewinfo + * $viewinfo + * + * All views for traversable collections are defined by creating a new `foreach` method. + * @author Martin Odersky * @version 2.8 + * @since 2.8 + * @tparam A the element type of the view + * @tparam Coll the type of the underlying collection containing the elements. + * @tparam This the type of the view itself */ trait TraversableViewLike[+A, +Coll, diff --git a/src/library/scala/collection/generic/BitSetFactory.scala b/src/library/scala/collection/generic/BitSetFactory.scala index cd26dc14b5..5679b25351 100644 --- a/src/library/scala/collection/generic/BitSetFactory.scala +++ b/src/library/scala/collection/generic/BitSetFactory.scala @@ -15,8 +15,17 @@ package generic import scala.collection._ import mutable.{Builder, AddingBuilder} -/** - * @since 2.8 +/** @define coll collection + * @define Coll Traversable + * @define factoryInfo + * This object provides a set of operations to create `$Coll` values. + * @author Martin Odersky + * @version 2.8 + * @define canBuildFromInfo + * The standard `CanBuildFrom` instance for $Coll objects. + * @see CanBuildFrom + * @define bitsetCanBuildFrom + * The standard `CanBuildFrom` instance for bitsets. */ trait BitSetFactory[Coll <: BitSet with BitSetLike[Coll]] { def newBuilder: Builder[Int, Coll] = new AddingBuilder[Int, Coll](empty) diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala index 49fa692ebf..fc04f28f26 100644 --- a/src/library/scala/collection/generic/MapFactory.scala +++ b/src/library/scala/collection/generic/MapFactory.scala @@ -14,10 +14,22 @@ package generic import mutable.{Builder, MapBuilder} -/** A template for companion objects of <code>mutable.Map</code> and - * subclasses thereof. +/** A template for companion objects of `Map` and subclasses thereof. * - * @since 2.8 + * @define coll map + * @define Coll Map + * @define factoryInfo + * This object provides a set of operations needed to create `$Coll` values. + * @author Martin Odersky + * @version 2.8 + * @define canBuildFromInfo + * The standard `CanBuildFrom` instance for `$Coll` objects. + * @see CanBuildFrom + * @define mapCanBuildFromInfo + * The standard `CanBuildFrom` instance for `$Coll` objects. + * The created value is an instance of class `MapCanBuildFrom`. + * @see CanBuildFrom + * @see GenericCanBuildFrom */ abstract class MapFactory[CC[A, B] <: Map[A, B] with MapLike[A, B, CC[A, B]]] { diff --git a/src/library/scala/collection/generic/MutableMapFactory.scala b/src/library/scala/collection/generic/MutableMapFactory.scala index 4ad9fb59e4..0f1608ee71 100644 --- a/src/library/scala/collection/generic/MutableMapFactory.scala +++ b/src/library/scala/collection/generic/MutableMapFactory.scala @@ -14,7 +14,7 @@ package generic import mutable.MapBuilder -/** A template for companion objects of mutable.Map and subclasses thereof. +/** A template for companion objects of `mutable.Map` and subclasses thereof. * * @since 2.8 */ diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala index de2baaa222..6a237d453c 100644 --- a/src/library/scala/collection/generic/SetFactory.scala +++ b/src/library/scala/collection/generic/SetFactory.scala @@ -17,7 +17,19 @@ import mutable.{Builder, AddingBuilder} /** A template for companion objects of <code>Set</code> and subclasses * thereof. * - * @since 2.8 + * @define coll set + * @define Coll Set + * @define factoryInfo + * This object provides a set of operations needed to create `$Coll` values. + * @author Martin Odersky + * @version 2.8 + * @define canBuildFromInfo + * The standard `CanBuildFrom` instance for `$Coll` objects. + * @see CanBuildFrom + * @define setCanBuildFromInfo + * The standard `CanBuildFrom` instance for `$Coll` objects. + * @see CanBuildFrom + * @see GenericCanBuildFrom */ abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]] extends GenericCompanion[CC] { diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala index c2668b48a2..b7fda70922 100644 --- a/src/library/scala/collection/generic/TraversableFactory.scala +++ b/src/library/scala/collection/generic/TraversableFactory.scala @@ -17,8 +17,8 @@ package generic * * @since 2.8 * - * @define $coll collection - * @define @Coll Traversable + * @define coll collection + * @define Coll Traversable * @define factoryInfo * This object provides a set of operations to create `$Coll` values. * @author Martin Odersky diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala index e06218ff92..857b537904 100644 --- a/src/library/scala/collection/immutable/BitSet.scala +++ b/src/library/scala/collection/immutable/BitSet.scala @@ -15,12 +15,8 @@ package immutable import generic._ import BitSetLike.{LogWL, updateArray} -/** A base class for immutable bit sets. +/** A class for immutable bitsets. * $bitsetinfo - * - * @author Martin Odersky - * @version 2.8 - * @since 1 */ @serializable @SerialVersionUID(1611436763290191562L) abstract class BitSet extends Set[Int] diff --git a/src/library/scala/collection/immutable/DefaultMap.scala b/src/library/scala/collection/immutable/DefaultMap.scala index 7ee8197150..a19b35aff0 100755 --- a/src/library/scala/collection/immutable/DefaultMap.scala +++ b/src/library/scala/collection/immutable/DefaultMap.scala @@ -19,7 +19,8 @@ import generic._ * methods of maps.<br/> * Instances that inherit from <code>DefaultMap[A, B]</code> still have to * define: - * </p><pre> + * </p> + * <pre> * <b>def</b> get(key: A): Option[B] * <b>def</b> iterator: Iterator[(A, B)]</pre> * <p> diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index 16d4473de1..e79b456a2f 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -15,12 +15,11 @@ package immutable import generic._ import annotation.unchecked.uncheckedVariance -/** <p> - * This class implements immutable sets using a hash trie. - * </p> +/** + * This class implements immutable sets using a hash trie. * - * @note the builder of a hash set returns specialized representations EmptySet,Set1,..., Set4 - * for sets of size <= 4. + * @note the builder of a hash set returns specialized representations `EmptySet`,`Set1`,..., `Set4` + * for sets of `size <= 4`. * * @author Martin Odersky * @author Tiark Rompf diff --git a/src/library/scala/collection/immutable/IndexedSeq.scala b/src/library/scala/collection/immutable/IndexedSeq.scala index 3f29052808..268bd56a85 100644 --- a/src/library/scala/collection/immutable/IndexedSeq.scala +++ b/src/library/scala/collection/immutable/IndexedSeq.scala @@ -15,10 +15,8 @@ import generic._ import mutable.{ArrayBuffer, Builder} /** A subtrait of <code>collection.IndexedSeq</code> which represents indexed sequences - * that cannot be mutated. + * that are guaranteed immutable. * $indexedSeqInfo - * - * @since 2.8 */ trait IndexedSeq[+A] extends Seq[A] with scala.collection.IndexedSeq[A] @@ -27,8 +25,9 @@ trait IndexedSeq[+A] extends Seq[A] override def companion: GenericCompanion[IndexedSeq] = IndexedSeq } -/** - * @since 2.8 +/** $factoryInfo + * @define coll indexed sequence + * @define Coll IndexedSeq */ object IndexedSeq extends SeqFactory[IndexedSeq] { @serializable diff --git a/src/library/scala/collection/immutable/IntMap.scala b/src/library/scala/collection/immutable/IntMap.scala index 62309a9f48..75a25e0223 100644 --- a/src/library/scala/collection/immutable/IntMap.scala +++ b/src/library/scala/collection/immutable/IntMap.scala @@ -167,6 +167,8 @@ sealed abstract class IntMap[+T] extends Map[Int, T] with MapLike[Int, T, IntMap /** * Iterator over key, value pairs of the map in unsigned order of the keys. + * + * @return an iterator over pairs of integer keys and corresponding values. */ def iterator : Iterator[(Int, T)] = this match { case IntMap.Nil => Iterator.empty; @@ -278,15 +280,20 @@ sealed abstract class IntMap[+T] extends Map[Int, T] with MapLike[Int, T, IntMap /** * Updates the map, using the provided function to resolve conflicts if the key is already present. - * Equivalent to - * <pre>this.get(key) match { - * case None => this.update(key, value); - * case Some(oldvalue) => this.update(key, f(oldvalue, value) } - * </pre> * - * @param key The key to update - * @param value The value to use if there is no conflict - * @param f The function used to resolve conflicts. + * Equivalent to: + * {{{ + * this.get(key) match { + * case None => this.update(key, value); + * case Some(oldvalue) => this.update(key, f(oldvalue, value) + * } + * }}} + * + * @tparam S The supertype of values in this `LongMap`. + * @param key The key to update + * @param value The value to use if there is no conflict + * @param f The function used to resolve conflicts. + * @return The updated map. */ def updateWith[S >: T](key : Int, value : S, f : (T, S) => S) : IntMap[S] = this match { case IntMap.Bin(prefix, mask, left, right) => if (!hasMatch(key, prefix, mask)) join(key, IntMap.Tip(key, value), prefix, this); @@ -312,7 +319,9 @@ sealed abstract class IntMap[+T] extends Map[Int, T] with MapLike[Int, T, IntMap * A combined transform and filter function. Returns an IntMap such that for each (key, value) mapping * in this map, if f(key, value) == None the map contains no mapping for key, and if <code>f(key, value) * - * @param f The transforming function. + * @tparam S The type of the values in the resulting `LongMap`. + * @param f The transforming function. + * @return The modified map. */ def modifyOrRemove[S](f : (Int, T) => Option[S]) : IntMap[S] = this match { case IntMap.Bin(prefix, mask, left, right) => { @@ -335,8 +344,10 @@ sealed abstract class IntMap[+T] extends Map[Int, T] with MapLike[Int, T, IntMap /** * Forms a union map with that map, using the combining function to resolve conflicts. * - * @param that the map to form a union with. - * @param f the function used to resolve conflicts between two mappings. + * @tparam S The type of values in `that`, a supertype of values in `this`. + * @param that The map to form a union with. + * @param f The function used to resolve conflicts between two mappings. + * @return Union of `this` and `that`, with identical key conflicts resolved using the function `f`. */ def unionWith[S >: T](that : IntMap[S], f : (Int, S, S) => S) : IntMap[S] = (this, that) match{ case (IntMap.Bin(p1, m1, l1, r1), that@(IntMap.Bin(p2, m2, l2, r2))) => @@ -364,8 +375,11 @@ sealed abstract class IntMap[+T] extends Map[Int, T] with MapLike[Int, T, IntMap * a map that has only keys present in both maps and has values produced from the original mappings * by combining them with f. * - * @param that The map to intersect with. - * @param f The combining function. + * @tparam S The type of values in `that`. + * @tparam R The type of values in the resulting `LongMap`. + * @param that The map to intersect with. + * @param f The combining function. + * @return Intersection of `this` and `that`, with values for identical keys produced by function `f`. */ def intersectionWith[S, R](that : IntMap[S], f : (Int, T, S) => R) : IntMap[R] = (this, that) match { case (IntMap.Bin(p1, m1, l1, r1), that@IntMap.Bin(p2, m2, l2, r2)) => @@ -394,7 +408,9 @@ sealed abstract class IntMap[+T] extends Map[Int, T] with MapLike[Int, T, IntMap * Left biased intersection. Returns the map that has all the same mappings as this but only for keys * which are present in the other map. * - * @param that The map to intersect with. + * @tparam R The type of values in `that`. + * @param that The map to intersect with. + * @return A map with all the keys both in `this` and `that`, mapped to corresponding values from `this`. */ def intersection[R](that : IntMap[R]) : IntMap[T] = this.intersectionWith(that, (key : Int, value : T, value2 : R) => value); diff --git a/src/library/scala/collection/immutable/Iterable.scala b/src/library/scala/collection/immutable/Iterable.scala index 77e16a6509..795fc2fa92 100644 --- a/src/library/scala/collection/immutable/Iterable.scala +++ b/src/library/scala/collection/immutable/Iterable.scala @@ -15,13 +15,8 @@ package immutable import generic._ import mutable.Builder -/** A subtrait of scala.collection.Iterable which represents iterables - * that cannot be mutated. - * - * @author Matthias Zenger - * @author Martin Odersky - * @version 2.8 - * @since 2.8 +/** A base trait for iterable collections that are guaranteed immutable. + * $iterableInfo */ trait Iterable[+A] extends Traversable[A] with scala.collection.Iterable[A] diff --git a/src/library/scala/collection/immutable/LinearSeq.scala b/src/library/scala/collection/immutable/LinearSeq.scala index 016afd4508..9cb35dced5 100644 --- a/src/library/scala/collection/immutable/LinearSeq.scala +++ b/src/library/scala/collection/immutable/LinearSeq.scala @@ -15,10 +15,9 @@ package immutable import generic._ import mutable.Builder -/** A subtrait of <code>collection.LinearSeq</code> which represents sequences - * that cannot be mutated. +/** A subtrait of <code>collection.LinearSeq</code> which represents sequences that + * are guaranteed immutable. * $linearSeqInfo - * @since 2.8 */ trait LinearSeq[+A] extends Seq[A] with scala.collection.LinearSeq[A] @@ -27,8 +26,9 @@ trait LinearSeq[+A] extends Seq[A] override def companion: GenericCompanion[LinearSeq] = LinearSeq } -/** - * @since 2.8 +/** $factoryInfo + * @define coll linear sequence + * @define Coll LinearSeq */ object LinearSeq extends SeqFactory[LinearSeq] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, LinearSeq[A]] = new GenericCanBuildFrom[A] diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index 2b91ab8852..4ce441ca55 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -433,7 +433,10 @@ final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extend } } -/** $factoryInfo */ +/** $factoryInfo + * @define coll list + * @define Coll List + */ object List extends SeqFactory[List] { import scala.collection.{Iterable, Seq, IndexedSeq} diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index d8e3e0856b..4342e54a9d 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -104,6 +104,8 @@ class ListMap[A, +B] extends Map[A, B] with MapLike[A, B, ListMap[A, B]] { protected def value: B = throw new NoSuchElementException("empty map") protected def next: ListMap[A, B] = throw new NoSuchElementException("empty map") + /** This class represents an entry in the `ListMap`. + */ @serializable @SerialVersionUID(-6453056603889598734L) protected class Node[B1 >: B](override protected val key: A, override protected val value: B1) extends ListMap[A, B1] { diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index 3863c16591..f7b76d2317 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -85,6 +85,8 @@ class ListSet[A] extends Set[A] */ protected def next: ListSet[A] = throw new NoSuchElementException("Next of an empty set"); + /** Represents an entry in the `ListSet`. + */ @serializable protected class Node(override protected val elem: A) extends ListSet[A] { diff --git a/src/library/scala/collection/immutable/LongMap.scala b/src/library/scala/collection/immutable/LongMap.scala index 0d74e41cec..24afb65b99 100644 --- a/src/library/scala/collection/immutable/LongMap.scala +++ b/src/library/scala/collection/immutable/LongMap.scala @@ -153,6 +153,8 @@ sealed abstract class LongMap[+T] extends Map[Long, T] with MapLike[Long, T, Lon /** * Iterator over key, value pairs of the map in unsigned order of the keys. + * + * @return an iterator over pairs of long keys and corresponding values. */ def iterator: Iterator[(Long, T)] = this match { case LongMap.Nil => Iterator.empty; @@ -264,15 +266,20 @@ sealed abstract class LongMap[+T] extends Map[Long, T] with MapLike[Long, T, Lon /** * Updates the map, using the provided function to resolve conflicts if the key is already present. + * * Equivalent to - * <pre>this.get(key) match { - * case None => this.update(key, value); - * case Some(oldvalue) => this.update(key, f(oldvalue, value) } - * </pre> + * {{{ + * this.get(key) match { + * case None => this.update(key, value); + * case Some(oldvalue) => this.update(key, f(oldvalue, value) + * } + * }}} * - * @param key The key to update - * @param value The value to use if there is no conflict - * @param f The function used to resolve conflicts. + * @tparam S The supertype of values in this `LongMap`. + * @param key The key to update. + * @param value The value to use if there is no conflict. + * @param f The function used to resolve conflicts. + * @return The updated map. */ def updateWith[S >: T](key : Long, value : S, f : (T, S) => S) : LongMap[S] = this match { case LongMap.Bin(prefix, mask, left, right) => if (!hasMatch(key, prefix, mask)) join(key, LongMap.Tip(key, value), prefix, this); @@ -298,7 +305,9 @@ sealed abstract class LongMap[+T] extends Map[Long, T] with MapLike[Long, T, Lon * A combined transform and filter function. Returns an LongMap such that for each (key, value) mapping * in this map, if f(key, value) == None the map contains no mapping for key, and if <code>f(key, value) * - * @param f The transforming function. + * @tparam S The type of the values in the resulting `LongMap`. + * @param f The transforming function. + * @return The modified map. */ def modifyOrRemove[S](f : (Long, T) => Option[S]) : LongMap[S] = this match { case LongMap.Bin(prefix, mask, left, right) => { @@ -321,8 +330,10 @@ sealed abstract class LongMap[+T] extends Map[Long, T] with MapLike[Long, T, Lon /** * Forms a union map with that map, using the combining function to resolve conflicts. * - * @param that the map to form a union with. - * @param f the function used to resolve conflicts between two mappings. + * @tparam S The type of values in `that`, a supertype of values in `this`. + * @param that The map to form a union with. + * @param f The function used to resolve conflicts between two mappings. + * @return Union of `this` and `that`, with identical key conflicts resolved using the function `f`. */ def unionWith[S >: T](that : LongMap[S], f : (Long, S, S) => S) : LongMap[S] = (this, that) match{ case (LongMap.Bin(p1, m1, l1, r1), that@(LongMap.Bin(p2, m2, l2, r2))) => @@ -350,8 +361,11 @@ sealed abstract class LongMap[+T] extends Map[Long, T] with MapLike[Long, T, Lon * a map that has only keys present in both maps and has values produced from the original mappings * by combining them with f. * - * @param that The map to intersect with. - * @param f The combining function. + * @tparam S The type of values in `that`. + * @tparam R The type of values in the resulting `LongMap`. + * @param that The map to intersect with. + * @param f The combining function. + * @return Intersection of `this` and `that`, with values for identical keys produced by function `f`. */ def intersectionWith[S, R](that : LongMap[S], f : (Long, T, S) => R) : LongMap[R] = (this, that) match { case (LongMap.Bin(p1, m1, l1, r1), that@LongMap.Bin(p2, m2, l2, r2)) => @@ -380,7 +394,9 @@ sealed abstract class LongMap[+T] extends Map[Long, T] with MapLike[Long, T, Lon * Left biased intersection. Returns the map that has all the same mappings as this but only for keys * which are present in the other map. * - * @param that The map to intersect with. + * @tparam R The type of values in `that`. + * @param that The map to intersect with. + * @return A map with all the keys both in `this` and `that`, mapped to corresponding values from `this`. */ def intersection[R](that : LongMap[R]) : LongMap[T] = this.intersectionWith(that, (key : Long, value : T, value2 : R) => value); diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala index b5a852683a..e3469099b8 100644 --- a/src/library/scala/collection/immutable/Map.scala +++ b/src/library/scala/collection/immutable/Map.scala @@ -15,6 +15,16 @@ package immutable import generic._ /** + * A generic trait for immutable maps. Concrete classes have to provide + * functionality for the abstract methods in `Map`: + * + * {{{ + * def get(key: A): Option[B] + * def iterator: Iterator[(A, B)] + * def + [B1 >: B](kv: (A, B1)): Map[A, B1] + * def -(key: A): Map[A, B] + * }}} + * * @since 1 */ trait Map[A, +B] extends Iterable[(A, B)] @@ -39,6 +49,8 @@ trait Map[A, +B] extends Iterable[(A, B)] } /** + * A companion object for immutable maps. + * * @since 1 */ object Map extends ImmutableMapFactory[Map] { diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala index 662321bb0c..6f816ffa52 100644 --- a/src/library/scala/collection/immutable/MapLike.scala +++ b/src/library/scala/collection/immutable/MapLike.scala @@ -91,13 +91,10 @@ trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] } /** Transforms this map by applying a function to every retrieved value. - * @param d the function used to transform values of this map. - * @return an immutable map which maps every key of this map + * @param f the function used to transform values of this map. + * @return a map view which maps every key of this map * to `f(this(key))`. The resulting map wraps the original map without copying any elements. */ - /** A map view resulting from applying a given function `f` to each value - * associated with a key in this map. - */ override def mapValues[C](f: B => C): Map[A, C] = new DefaultMap[A, C] { override def foreach[D](g: ((A, C)) => D): Unit = for ((k, v) <- self) g((k, f(v))) def iterator = for ((k, v) <- self.iterator) yield (k, f(v)) diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index d3e4558884..645c5fed24 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -17,12 +17,12 @@ import generic._ /** <p> * <code>NumericRange</code> is a more generic version of the * <code>Range</code> class which works with arbitrary types. - * It must be supplied with an Integral implementation of the + * It must be supplied with an `Integral` implementation of the * range type. * - * Factories for likely types include Range.BigInt, Range.Long, - * and Range.BigDecimal. Range.Int exists for completeness, but - * the Int-based scala.Range should be more performant. + * Factories for likely types include `Range.BigInt`, `Range.Long`, + * and `Range.BigDecimal`. `Range.Int` exists for completeness, but + * the `Int`-based `scala.Range` should be more performant. * </p><pre> * <b>val</b> r1 = new Range(0, 100, 1) * <b>val</b> veryBig = Int.MaxValue.toLong + 1 diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 43b11b67be..5424a7afcb 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -32,14 +32,14 @@ class Range(val start: Int, val end: Int, val step: Int) extends IndexedSeq[Int] protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step) - /** Create a new range with the start and end values of this range and + /** Create a new range with the `start` and `end` values of this range and * a new <code>step</code>. */ def by(step: Int): Range = copy(start, end, step) def isInclusive = false - override def foreach[U](f: Int => U) { + override def foreach[@specialized(Unit) U](f: Int => U) { if (fullLength > 0) { val last = this.last var i = start @@ -191,7 +191,7 @@ object Range { def inclusive(start: Int, end: Int): Range.Inclusive with ByOne = new Inclusive(start, end, 1) with ByOne trait ByOne extends Range { - override final def foreach[U](f: Int => U) { + override final def foreach[@specialized(Unit) U](f: Int => U) { if (length > 0) { val last = this.last var i = start diff --git a/src/library/scala/collection/immutable/RedBlack.scala b/src/library/scala/collection/immutable/RedBlack.scala index e7b4f3c978..ffa6194838 100644 --- a/src/library/scala/collection/immutable/RedBlack.scala +++ b/src/library/scala/collection/immutable/RedBlack.scala @@ -12,7 +12,7 @@ package scala.collection package immutable -/** An base class containing the implementations for TreeMaps and TreeSets +/** A base class containing the implementations for TreeMaps and TreeSets * * @since 2.3 */ diff --git a/src/library/scala/collection/immutable/Seq.scala b/src/library/scala/collection/immutable/Seq.scala index 9bd7084675..de7804a95c 100644 --- a/src/library/scala/collection/immutable/Seq.scala +++ b/src/library/scala/collection/immutable/Seq.scala @@ -15,10 +15,10 @@ package immutable import generic._ import mutable.Builder -/** A subtrait of collection.Seq which represents sequences - * that cannot be mutated. +/** A subtrait of `collection.Seq` which represents sequences + * that are guaranteed immutable. * - * @since 2.8 + * $seqInfo */ trait Seq[+A] extends Iterable[A] with scala.collection.Seq[A] diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala index 1bec1b9a48..77f16c0d14 100644 --- a/src/library/scala/collection/immutable/Set.scala +++ b/src/library/scala/collection/immutable/Set.scala @@ -39,6 +39,9 @@ trait Set[A] extends Iterable[A] override def companion: GenericCompanion[Set] = Set } +/** + * A companion object for immutable sets. + */ object Set extends SetFactory[Set] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A] override def empty[A]: Set[A] = EmptySet.asInstanceOf[Set[A]] diff --git a/src/library/scala/collection/immutable/SortedSet.scala b/src/library/scala/collection/immutable/SortedSet.scala index 9d0b1882fa..10ff466ff8 100644 --- a/src/library/scala/collection/immutable/SortedSet.scala +++ b/src/library/scala/collection/immutable/SortedSet.scala @@ -15,7 +15,8 @@ package immutable import generic._ import mutable.Builder -/** A sorted set. +/** A subtrait of `collection.SortedSet` which represents sorted sets + * which cannot be mutated. * * @author Sean McDirmid * @author Martin Odersky @@ -28,6 +29,8 @@ trait SortedSet[A] extends Set[A] with scala.collection.SortedSet[A] with Sorted } /** + * A companion object for immutable sorted sets. + * * @since 2.4 */ object SortedSet extends ImmutableSortedSetFactory[SortedSet] { diff --git a/src/library/scala/collection/immutable/Stack.scala b/src/library/scala/collection/immutable/Stack.scala index 640fb39af5..7d3c8c040b 100644 --- a/src/library/scala/collection/immutable/Stack.scala +++ b/src/library/scala/collection/immutable/Stack.scala @@ -67,8 +67,8 @@ class Stack[+A] protected (protected val elems: List[A]) extends LinearSeq[A] def push[B >: A](elem1: B, elem2: B, elems: B*): Stack[B] = this.push(elem1).push(elem2).pushAll(elems) - /** Push all elements provided by the given iterator object onto - * the stack. The last element returned by the iterable object + /** Push all elements provided by the given traversable object onto + * the stack. The last element returned by the traversable object * will be on top of the new stack. * * @param elems the iterator object. diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 5b5a627cfe..8068267dd2 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -49,7 +49,7 @@ self => override def mkString = toString - /** return n times the current string + /** Return the current string concatenated `n` times. */ def * (n: Int): String = { val buf = new StringBuilder @@ -61,18 +61,16 @@ self => private def isLineBreak(c: Char) = c == LF || c == FF - /** <p> + /** * Strip trailing line end character from this string if it has one. + * * A line end character is one of - * </p> - * <ul style="list-style-type: none;"> - * <li>LF - line feed (0x0A hex)</li> - * <li>FF - form feed (0x0C hex)</li> - * </ul> - * <p> + * <ul style="list-style-type: none;"> + * <li>LF - line feed (0x0A hex)</li> + * <li>FF - form feed (0x0C hex)</li> + * </ul> * If a line feed character LF is preceded by a carriage return CR * (0x0D hex), the CR character is also stripped (Windows convention). - * </p> */ def stripLineEnd: String = { val len = toString.length @@ -86,19 +84,18 @@ self => } } - /** <p> + /** * Return all lines in this string in an iterator, including trailing * line end characters. - * </p> - * <p> + * * The number of strings returned is one greater than the number of line * end characters in this string. For an empty string, a single empty * line is returned. A line end character is one of - * </p> - * <ul style="list-style-type: none;"> - * <li>LF - line feed (0x0A hex)</li> - * <li>FF - form feed (0x0C hex)</li> - * </ul> + * + * <ul style="list-style-type: none;"> + * <li>LF - line feed (0x0A hex)</li> + * <li>FF - form feed (0x0C hex)</li> + * </ul> */ def linesWithSeparators: Iterator[String] = new Iterator[String] { val str = self.toString @@ -148,13 +145,13 @@ self => if (toString.endsWith(suffix)) toString.substring(0, toString.length() - suffix.length) else toString - /** <p> + /** * For every line in this string: - * </p> - * <blockquote> - * Strip a leading prefix consisting of blanks or control characters - * followed by <code>marginChar</code> from the line. - * </blockquote> + * + * <blockquote> + * Strip a leading prefix consisting of blanks or control characters + * followed by <code>marginChar</code> from the line. + * </blockquote> */ def stripMargin(marginChar: Char): String = { val buf = new StringBuilder @@ -168,13 +165,13 @@ self => buf.toString } - /** <p> + /** * For every line in this string: - * </p> - * <blockquote> - * Strip a leading prefix consisting of blanks or control characters - * followed by <code>|</code> from the line. - * </blockquote> + * + * <blockquote> + * Strip a leading prefix consisting of blanks or control characters + * followed by <code>|</code> from the line. + * </blockquote> */ def stripMargin: String = stripMargin('|') @@ -226,19 +223,18 @@ self => case x => x.asInstanceOf[AnyRef] } - /** <p> + /** * Uses the underlying string as a pattern (in a fashion similar to * printf in C), and uses the supplied arguments to fill in the * holes. - * </p> - * <p> + * * The interpretation of the formatting patterns is described in * <a href="" target="contentFrame" class="java/util/Formatter"> * <code>java.util.Formatter</code></a>, with the addition that - * classes deriving from ScalaNumber (such as scala.BigInt and - * scala.BigDecimal) are unwrapped to pass a type which Formatter + * classes deriving from `ScalaNumber` (such as `scala.BigInt` and + * `scala.BigDecimal`) are unwrapped to pass a type which `Formatter` * understands. - * </p> + * * * @param args the arguments used to instantiating the pattern. * @throws java.lang.IllegalArgumentException @@ -246,20 +242,20 @@ self => def format(args : Any*): String = java.lang.String.format(toString, args map unwrapArg: _*) - /** <p> - * Like format(args*) but takes an initial Locale parameter - * which influences formatting as in java.lang.String's format. - * </p> - * <p> + /** + * Like `format(args*)` but takes an initial `Locale` parameter + * which influences formatting as in `java.lang.String`'s format. + * + * * The interpretation of the formatting patterns is described in * <a href="" target="contentFrame" class="java/util/Formatter"> * <code>java.util.Formatter</code></a>, with the addition that - * classes deriving from ScalaNumber (such as scala.BigInt and - * scala.BigDecimal) are unwrapped to pass a type which Formatter + * classes deriving from `ScalaNumber` (such as `scala.BigInt` and + * `scala.BigDecimal`) are unwrapped to pass a type which `Formatter` * understands. - * </p> * - * @param locale an instance of java.util.Locale + * + * @param locale an instance of `java.util.Locale` * @param args the arguments used to instantiating the pattern. * @throws java.lang.IllegalArgumentException */ diff --git a/src/library/scala/collection/immutable/StringOps.scala b/src/library/scala/collection/immutable/StringOps.scala index 95509ab9d6..4949eb7056 100644 --- a/src/library/scala/collection/immutable/StringOps.scala +++ b/src/library/scala/collection/immutable/StringOps.scala @@ -15,6 +15,14 @@ package immutable import mutable.StringBuilder /** + * This class serves as a wrapper providing `String`s with all the operations + * found in indexed sequences. Where needed, instances of `String` object + * are implicitly converted into this class. + * + * The difference between this class and `WrappedString` is that calling transformer + * methods such as `filter` and `map` will yield a `String` object, whereas a + * `WrappedString` will remain a `WrappedString`. + * * @since 2.8 */ final class StringOps(override val repr: String) extends StringLike[String] { diff --git a/src/library/scala/collection/immutable/Traversable.scala b/src/library/scala/collection/immutable/Traversable.scala index b0934ece85..af7f6979c9 100644 --- a/src/library/scala/collection/immutable/Traversable.scala +++ b/src/library/scala/collection/immutable/Traversable.scala @@ -15,13 +15,9 @@ package immutable import generic._ import mutable.Builder -/** A subtrait of <code>collection.Traversable</code> which represents - * traversables that cannot be mutated. - * - * @author Matthias Zenger - * @author Martin Odersky - * @version 2.8 - * @since 2.8 +/** A trait for traversable collections that are guaranteed immutable. + * $traversableInfo + * @define mutability immutable */ trait Traversable[+A] extends scala.collection.Traversable[A] with GenericTraversableTemplate[A, Traversable] diff --git a/src/library/scala/collection/immutable/WrappedString.scala b/src/library/scala/collection/immutable/WrappedString.scala index e10b3ab0ee..cefbd96b5c 100644 --- a/src/library/scala/collection/immutable/WrappedString.scala +++ b/src/library/scala/collection/immutable/WrappedString.scala @@ -17,6 +17,13 @@ import mutable.{Builder, StringBuilder} import scala.util.matching.Regex /** + * This class serves as a wrapper augmenting `String`s with all the operations + * found in indexed sequences. + * + * The difference between this class and `StringOps` is that calling transformer + * methods such as `filter` and `map` will yield an object of type `WrappedString` + * rather than a `String`. + * * @since 2.8 */ class WrappedString(override val self: String) extends IndexedSeq[Char] with StringLike[WrappedString] with Proxy { diff --git a/src/library/scala/collection/mutable/AddingBuilder.scala b/src/library/scala/collection/mutable/AddingBuilder.scala index d16a4a71f3..14636c9feb 100644 --- a/src/library/scala/collection/mutable/AddingBuilder.scala +++ b/src/library/scala/collection/mutable/AddingBuilder.scala @@ -15,6 +15,7 @@ import generic._ /** The canonical builder for collections that are addable, i.e. that support an efficient `+` method * which adds an element to the collection. + * * Collections are built from their empty element using this `+` method. * @param empty the empty element of the collection. * @tparam Elem the type of elements that get added to the builder. diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala index 0c6aa9ce0c..bee531221f 100644 --- a/src/library/scala/collection/mutable/ArrayBuffer.scala +++ b/src/library/scala/collection/mutable/ArrayBuffer.scala @@ -14,7 +14,7 @@ package mutable import generic._ -/** An implementation of the <code>Buffer</code> class using an array to +/** An implementation of the `Buffer` class using an array to * represent the assembled sequence internally. Append, update and random * access take constant time (amortized time). Prepends and removes are * linear in the buffer size. @@ -23,6 +23,22 @@ import generic._ * @author Martin Odersky * @version 2.8 * @since 1 + * + * @tparam A the type of this arraybuffer's elements. + * + * @define Coll ArrayBuffer + * @define coll arraybuffer + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `ArrayBuffer[B]` because an implicit of type `CanBuildFrom[ArrayBuffer, B, ArrayBuffer[B]]` + * is defined in object `ArrayBuffer`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `ArrayBuffer`. + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @serializable @SerialVersionUID(1529165946227428979L) class ArrayBuffer[A](override protected val initialSize: Int) @@ -50,9 +66,10 @@ class ArrayBuffer[A](override protected val initialSize: Int) } /** Appends a single element to this buffer and returns - * the identity of the buffer. It takes constant time. + * the identity of the buffer. It takes constant amortized time. * * @param elem the element to append. + * @return the updated buffer. */ def +=(elem: A): this.type = { ensureSize(size0 + 1) @@ -61,11 +78,10 @@ class ArrayBuffer[A](override protected val initialSize: Int) this } - /** Appends a number of elements provided by an iterable object - * via its <code>iterator</code> method. The identity of the - * buffer is returned. + /** Appends a number of elements provided by a traversable object. + * The identity of the buffer is returned. * - * @param iter the iterable object. + * @param xs the traversable object. * @return the updated buffer. */ override def ++=(xs: TraversableOnce[A]): this.type = xs match { @@ -79,7 +95,7 @@ class ArrayBuffer[A](override protected val initialSize: Int) super.++=(xs) } - /** Prepends a single element to this buffer and return + /** Prepends a single element to this buffer and returns * the identity of the buffer. It takes time linear in * the buffer size. * @@ -94,22 +110,21 @@ class ArrayBuffer[A](override protected val initialSize: Int) this } - /** Prepends a number of elements provided by an iterable object - * via its <code>iterator</code> method. The identity of the - * buffer is returned. + /** Prepends a number of elements provided by a traversable object. + * The identity of the buffer is returned. * - * @param iter the iterable object. + * @param xs the traversable object. * @return the updated buffer. */ override def ++=:(xs: TraversableOnce[A]): this.type = { insertAll(0, xs.toTraversable); this } - /** Inserts new elements at the index <code>n</code>. Opposed to method - * <code>update</code>, this method will not replace an element with a - * one. Instead, it will insert a new element at index <code>n</code>. + /** Inserts new elements at the index `n`. Opposed to method + * `update`, this method will not replace an element with a + * one. Instead, it will insert a new element at index `n`. * * @param n the index where a new element will be inserted. - * @param iter the iterable object providing all elements to insert. - * @throws Predef.IndexOutOfBoundsException if <code>n</code> is out of bounds. + * @param seq the traversable object providing all elements to insert. + * @throws Predef.IndexOutOfBoundsException if `n` is out of bounds. */ def insertAll(n: Int, seq: Traversable[A]) { if (n < 0 || n > size0) throw new IndexOutOfBoundsException(n.toString) @@ -124,9 +139,9 @@ class ArrayBuffer[A](override protected val initialSize: Int) /** Removes the element on a given index position. It takes time linear in * the buffer size. * - * @param n the index which refers to the first element to delete. + * @param n the index which refers to the first element to delete. * @param count the number of elements to delete - * @throws Predef.IndexOutOfBoundsException if <code>n</code> is out of bounds. + * @throws Predef.IndexOutOfBoundsException if `n` is out of bounds. */ override def remove(n: Int, count: Int) { require(count >= 0, "removing negative number of elements") @@ -135,10 +150,10 @@ class ArrayBuffer[A](override protected val initialSize: Int) reduceToSize(size0 - count) } - /** Removes the element on a given index position + /** Removes the element at a given index position. * * @param n the index which refers to the element to delete. - * @return The element that was formerly at position `n` + * @return the element that was formerly at position `n`. */ def remove(n: Int): A = { val result = apply(n) @@ -148,7 +163,7 @@ class ArrayBuffer[A](override protected val initialSize: Int) /** Return a clone of this buffer. * - * @return an <code>ArrayBuffer</code> with the same elements. + * @return an `ArrayBuffer` with the same elements. */ override def clone(): ArrayBuffer[A] = new ArrayBuffer[A] ++= this @@ -159,13 +174,14 @@ class ArrayBuffer[A](override protected val initialSize: Int) override def stringPrefix: String = "ArrayBuffer" } -/** Factory object for <code>ArrayBuffer</code> class. +/** Factory object for the `ArrayBuffer` class. * - * @author Martin Odersky - * @version 2.8 - * @since 2.8 + * $factoryInfo + * @define coll list + * @define Coll List */ object ArrayBuffer extends SeqFactory[ArrayBuffer] { + /** $genericCanBuildFromInfo */ implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, ArrayBuffer[A]] = new GenericCanBuildFrom[A] def newBuilder[A]: Builder[A, ArrayBuffer[A]] = new ArrayBuffer[A] } diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index 7e4bab353b..0ddd089852 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -15,21 +15,33 @@ package mutable import generic._ import scala.reflect.ClassManifest -/** A builder class for arrays +/** A builder class for arrays. * - * @since 2.8 + * @since 2.8 + * + * @tparam T the type of the elements for the builder. */ @serializable abstract class ArrayBuilder[T] extends Builder[T, Array[T]] -/** - * @since 2.8 +/** A companion object for array builders. + * + * @since 2.8 */ object ArrayBuilder { + /** Creates a new arraybuilder of type `T`. + * + * @tparam T type of the elements for the array builder, with a `ClassManifest` context bound. + * @return a new empty array builder. + */ def make[T: ClassManifest](): ArrayBuilder[T] = implicitly[ClassManifest[T]].newArrayBuilder() + /** A class for array builders for arrays of reference types. + * + * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassManifest` context bound. + */ class ofRef[T <: AnyRef : ClassManifest] extends ArrayBuilder[T] { private var elems: Array[T] = _ @@ -94,6 +106,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofRef" } + /** A class for array builders for arrays of `byte`s. */ class ofByte extends ArrayBuilder[Byte] { private var elems: Array[Byte] = _ @@ -158,6 +171,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofByte" } + /** A class for array builders for arrays of `short`s. */ class ofShort extends ArrayBuilder[Short] { private var elems: Array[Short] = _ @@ -222,6 +236,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofShort" } + /** A class for array builders for arrays of `char`s. */ class ofChar extends ArrayBuilder[Char] { private var elems: Array[Char] = _ @@ -286,6 +301,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofChar" } + /** A class for array builders for arrays of `int`s. */ class ofInt extends ArrayBuilder[Int] { private var elems: Array[Int] = _ @@ -350,6 +366,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofInt" } + /** A class for array builders for arrays of `long`s. */ class ofLong extends ArrayBuilder[Long] { private var elems: Array[Long] = _ @@ -414,6 +431,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofLong" } + /** A class for array builders for arrays of `float`s. */ class ofFloat extends ArrayBuilder[Float] { private var elems: Array[Float] = _ @@ -478,6 +496,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofFloat" } + /** A class for array builders for arrays of `double`s. */ class ofDouble extends ArrayBuilder[Double] { private var elems: Array[Double] = _ @@ -542,6 +561,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofDouble" } + /** A class for array builders for arrays of `boolean`s. */ class ofBoolean extends ArrayBuilder[Boolean] { private var elems: Array[Boolean] = _ @@ -606,6 +626,7 @@ object ArrayBuilder { override def toString = "ArrayBuilder.ofBoolean" } + /** A class for array builders for arrays of `Unit` type. */ class ofUnit extends ArrayBuilder[Unit] { private var elems: Array[Unit] = _ diff --git a/src/library/scala/collection/mutable/ArrayLike.scala b/src/library/scala/collection/mutable/ArrayLike.scala index 0b64f1255e..b3bd0fbe25 100644 --- a/src/library/scala/collection/mutable/ArrayLike.scala +++ b/src/library/scala/collection/mutable/ArrayLike.scala @@ -13,21 +13,31 @@ package scala.collection package mutable import generic._ -/** A subtrait of collection.IndexedSeq which represents sequences +/** A subtrait of `collection.IndexedSeq` which represents sequences * that can be mutated. * * @since 2.8 + * + * @tparam A type of the elements contained in the array like object. + * @tparam Repr the type of the actual collection containing the elements. + * + * @define Coll ArrayLike */ trait ArrayLike[A, +Repr] extends IndexedSeqOptimized[A, Repr] { self => - /** Creates a possible nested IndexedSeq which consists of all the elements - * of this array. If the elements are arrays themselves, the `deep' transformation - * is applied recursively to them. The stringPrefix of the IndexedSeq is - * "Array", hence the IndexedSeq prints like an array with all its + /** Creates a possible nested `IndexedSeq` which consists of all the elements + * of this array. If the elements are arrays themselves, the `deep` transformation + * is applied recursively to them. The `stringPrefix` of the `IndexedSeq` is + * "Array", hence the `IndexedSeq` prints like an array with all its * elements shown, and the same recursively for any subarrays. * - * Example: Array(Array(1, 2), Array(3, 4)).deep.toString - * prints: Array(Array(1, 2), Array(3, 4)) + * Example: + * {{{ + * Array(Array(1, 2), Array(3, 4)).deep.toString + * }}} + * prints: `Array(Array(1, 2), Array(3, 4))` + * + * @return An possibly nested indexed sequence of consisting of all the elements of the array. */ def deep: scala.collection.IndexedSeq[Any] = new scala.collection.IndexedSeq[Any] { def length = self.length diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 553461c805..971709ed67 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -14,8 +14,23 @@ package mutable import scala.reflect.ClassManifest -/** - * @since 2.8 +/** This class serves as a wrapper for `Array`s with all the operations found in + * indexed sequences. Where needed, instances of arrays are implicitly converted + * into this class. + * + * The difference between this class and `WrappedArray` is that calling transformer + * methods such as `filter` and `map` will yield an array, whereas a `WrappedArray` + * will remain a `WrappedArray`. + * + * @since 2.8 + * + * @tparam T type of the elements contained in this array. + * + * @define Coll ArrayOps + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] { @@ -31,7 +46,11 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] { super.toArray[U] /** Flattens a two-dimensional array by concatenating all its rows - * into a single array + * into a single array. + * + * @tparam U Type of row elements. + * @param asArray A function that converts elements of this array to rows - arrays of type `U`. + * @return An array obtained by concatenating rows of this array. */ def flatten[U](implicit asArray: T => /*<:<!!!*/ Array[U]): Array[U] = { val b = rowBuilder[U] @@ -40,7 +59,11 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] { b.result } - /** Transposes a two dimensional array + /** Transposes a two dimensional array. + * + * @tparam U Type of row elements. + * @param asArray A function that converts elements of this array to rows - arrays of type `U`. + * @return An array obtained by replacing elements of this arrays with rows the represent. */ def transpose[U](implicit asArray: T => Array[U]): Array[Array[U]] = { val bs = asArray(head) map (_ => rowBuilder[U]) @@ -60,10 +83,13 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] { } /** + * A companion object for `ArrayOps`. + * * @since 2.8 */ object ArrayOps { + /** A class of `ArrayOps` for arrays containing reference types. */ class ofRef[T <: AnyRef](override val repr: Array[T]) extends ArrayOps[T] with ArrayLike[T, Array[T]] { override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr) @@ -76,6 +102,7 @@ object ArrayOps { def update(index: Int, elem: T) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `byte`s. */ class ofByte(override val repr: Array[Byte]) extends ArrayOps[Byte] with ArrayLike[Byte, Array[Byte]] { override protected[this] def thisCollection: WrappedArray[Byte] = new WrappedArray.ofByte(repr) @@ -87,6 +114,7 @@ object ArrayOps { def update(index: Int, elem: Byte) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `short`s. */ class ofShort(override val repr: Array[Short]) extends ArrayOps[Short] with ArrayLike[Short, Array[Short]] { override protected[this] def thisCollection: WrappedArray[Short] = new WrappedArray.ofShort(repr) @@ -98,6 +126,7 @@ object ArrayOps { def update(index: Int, elem: Short) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `char`s. */ class ofChar(override val repr: Array[Char]) extends ArrayOps[Char] with ArrayLike[Char, Array[Char]] { override protected[this] def thisCollection: WrappedArray[Char] = new WrappedArray.ofChar(repr) @@ -109,6 +138,7 @@ object ArrayOps { def update(index: Int, elem: Char) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `int`s. */ class ofInt(override val repr: Array[Int]) extends ArrayOps[Int] with ArrayLike[Int, Array[Int]] { override protected[this] def thisCollection: WrappedArray[Int] = new WrappedArray.ofInt(repr) @@ -120,6 +150,7 @@ object ArrayOps { def update(index: Int, elem: Int) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `long`s. */ class ofLong(override val repr: Array[Long]) extends ArrayOps[Long] with ArrayLike[Long, Array[Long]] { override protected[this] def thisCollection: WrappedArray[Long] = new WrappedArray.ofLong(repr) @@ -131,6 +162,7 @@ object ArrayOps { def update(index: Int, elem: Long) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `float`s. */ class ofFloat(override val repr: Array[Float]) extends ArrayOps[Float] with ArrayLike[Float, Array[Float]] { override protected[this] def thisCollection: WrappedArray[Float] = new WrappedArray.ofFloat(repr) @@ -142,6 +174,7 @@ object ArrayOps { def update(index: Int, elem: Float) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `double`s. */ class ofDouble(override val repr: Array[Double]) extends ArrayOps[Double] with ArrayLike[Double, Array[Double]] { override protected[this] def thisCollection: WrappedArray[Double] = new WrappedArray.ofDouble(repr) @@ -153,6 +186,7 @@ object ArrayOps { def update(index: Int, elem: Double) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays containing `boolean`s. */ class ofBoolean(override val repr: Array[Boolean]) extends ArrayOps[Boolean] with ArrayLike[Boolean, Array[Boolean]] { override protected[this] def thisCollection: WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr) @@ -164,6 +198,7 @@ object ArrayOps { def update(index: Int, elem: Boolean) { repr(index) = elem } } + /** A class of `ArrayOps` for arrays of `Unit` types. */ class ofUnit(override val repr: Array[Unit]) extends ArrayOps[Unit] with ArrayLike[Unit, Array[Unit]] { override protected[this] def thisCollection: WrappedArray[Unit] = new WrappedArray.ofUnit(repr) diff --git a/src/library/scala/collection/mutable/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala index f6f958601d..d59cf684b2 100644 --- a/src/library/scala/collection/mutable/ArraySeq.scala +++ b/src/library/scala/collection/mutable/ArraySeq.scala @@ -21,6 +21,23 @@ import generic._ * @author Martin Odersky * @version 2.8 * @since 2.8 + * + * @tparam A type of the elements contained in this array sequence. + * @param length the length of the underlying array. + * + * @define Coll ArraySeq + * @define coll array sequence + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `ArraySeq[B]` because an implicit of type `CanBuildFrom[ArraySeq, B, ArraySeq[B]]` + * is defined in object `ArraySeq`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `ArraySeq`. + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ class ArraySeq[A](override val length: Int) extends IndexedSeq[A] @@ -49,7 +66,7 @@ extends IndexedSeq[A] } } - /** Fills the given array <code>xs</code> with at most `len` elements of + /** Fills the given array `xs` with at most `len` elements of * this traversable starting at position `start`. * Copying will stop once either the end of the current traversable is reached or * `len` elements have been copied or the end of the array is reached. @@ -64,7 +81,12 @@ extends IndexedSeq[A] } } +/** $factoryInfo + * @define coll array sequence + * @define Coll ArraySeq + */ object ArraySeq extends SeqFactory[ArraySeq] { + /** $genericCanBuildFromInfo */ implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, ArraySeq[A]] = new GenericCanBuildFrom[A] def newBuilder[A]: Builder[A, ArraySeq[A]] = new ArrayBuffer[A] mapResult { buf => diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala index 8f9d1bfc88..0c6dc7a0e1 100644 --- a/src/library/scala/collection/mutable/ArrayStack.scala +++ b/src/library/scala/collection/mutable/ArrayStack.scala @@ -28,12 +28,20 @@ private object Utils { } } -/** - * Simple stack class backed by an array. Should be significantly faster - * than the standard mutable stack. +/** Simple stack class backed by an array. Should be significantly faster + * than the standard mutable stack. * - * @author David MacIver - * @since 2.7 + * @author David MacIver + * @since 2.7 + * + * @tparam T type of the elements contained in this array stack. + * + * @define Coll ArrayStack + * @define coll array stack + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @cloneable @serializable @SerialVersionUID(8565219180626620510L) class ArrayStack[T] private(private var table : Array[AnyRef], @@ -47,10 +55,9 @@ class ArrayStack[T] private(private var table : Array[AnyRef], /** The number of elements in the stack */ def length = index - /** - * Push an element onto the stack. + /** Push an element onto the stack. * - * @param x The element to push + * @param x The element to push */ def push(x: T) { if (index == table.length) table = Utils.growArray(table) @@ -58,8 +65,9 @@ class ArrayStack[T] private(private var table : Array[AnyRef], index += 1 } - /** - * Pop the top element off the stack. + /** Pop the top element off the stack. + * + * @return the element on top of the stack */ def pop: T = { if (index == 0) error("Stack empty") @@ -73,68 +81,73 @@ class ArrayStack[T] private(private var table : Array[AnyRef], @deprecated("use top instead") def peek = top - /** - * View the top element of the stack. + /** View the top element of the stack. + * + * Does not remove the element on the top. If the stack is empty, + * an exception is thrown. + * + * @return the element on top of the stack. */ def top: T = table(index - 1).asInstanceOf[T] - /** - * Duplicate the top element of the stack. + /** Duplicate the top element of the stack. + * + * After calling this method, the stack will have an additional element at + * the top equal to the element that was previously at the top. + * If the stack is empty, an exception is thrown. */ def dup = push(top) - /** - * Empties the stack. - */ + /** Empties the stack. */ def clear { index = 0 table = new Array(1) } - /** - * Empties the stack, passing all elements on it in FIFO order to the - * provided function. + /** Empties the stack, passing all elements on it in LIFO order to the + * provided function. * - * @param f The function to drain to. + * @param f The function to drain to. */ def drain(f: T => Unit) = while (!isEmpty) f(pop) - /** - * Pushes all the provided elements onto the stack. + /** Pushes all the provided elements in the traversable object onto the stack. * - * @param x The source of elements to push + * @param x The source of elements to push. + * @return A reference to this stack. */ def ++=(xs: TraversableOnce[T]): this.type = { xs foreach += ; this } - /** - * Alias for push. + /** Does the same as `push`, but returns the updated stack. * - * @param x The element to push + * @param x The element to push. + * @return A reference to this stack. */ def +=(x: T): this.type = { push(x); this } - /** - * Pop the top two elements off the stack, apply f to them and push the result - * back on to the stack. + /** Pop the top two elements off the stack, apply `f` to them and push the result + * back on to the stack. * - * @param f The combining function + * This function will throw an exception if stack contains fewer than 2 elements. + * + * @param f The function to apply to the top two elements. */ - def combine(f: (T, T) => T) = push(f(pop, pop)); + def combine(f: (T, T) => T): Unit = push(f(pop, pop)) - /** - * Repeatedly combine the top elements of the stack until the stack contains only - * one element. + /** Repeatedly combine the top elements of the stack until the stack contains only + * one element. + * + * @param f The function to apply repeatedly to topmost elements. */ - def reduceWith(f: (T, T) => T) = while(size > 1) combine(f) + def reduceWith(f: (T, T) => T): Unit = while(size > 1) combine(f) override def size = index - /** - * Evaluates the expression, preserving the contents of the stack so that - * any changes the evaluation makes to the stack contents will be undone after - * it completes. + /** Evaluates the expression, preserving the contents of the stack so that + * any changes the evaluation makes to the stack contents will be undone after + * it completes. * - * @param action The action to run. + * @param action The action to run. */ def preserving[T](action: => T) = { val oldIndex = index @@ -150,8 +163,8 @@ class ArrayStack[T] private(private var table : Array[AnyRef], override def isEmpty: Boolean = index == 0 - /** - * Iterates over the stack in LIFO order. + /** Creates and iterator over the stack in LIFO order. + * @return an iterator over the elements of the stack. */ def iterator: Iterator[T] = new Iterator[T] { var currentIndex = index diff --git a/src/library/scala/collection/mutable/BitSet.scala b/src/library/scala/collection/mutable/BitSet.scala index 92dad18956..5d0f5863ca 100644 --- a/src/library/scala/collection/mutable/BitSet.scala +++ b/src/library/scala/collection/mutable/BitSet.scala @@ -16,11 +16,22 @@ import generic._ import BitSetLike.{LogWL, updateArray} /** A class for mutable bitsets. + * * $bitsetinfo * - * @author Martin Odersky - * @version 2.8 - * @since 1 + * @define Coll BitSet + * @define coll bitset + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `BitSet[B]` because an implicit of type `CanBuildFrom[BitSet, B, BitSet]` + * is defined in object `BitSet`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `BitSet`. + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @serializable @SerialVersionUID(8483111450368547763L) class BitSet(protected var elems: Array[Long]) extends Set[Int] @@ -30,6 +41,10 @@ class BitSet(protected var elems: Array[Long]) extends Set[Int] override def empty = BitSet.empty + /** Creates the bitset of a certain initial size. + * + * @param initSize initial size of the bitset. + */ def this(initSize: Int) = this(new Array[Long]((initSize + 63) >> 6 max 1)) def this() = this(0) @@ -79,7 +94,10 @@ class BitSet(protected var elems: Array[Long]) extends Set[Int] /** Wraps this bitset as an immutable bitset backed by the array of bits * of this bitset. + * * @note Subsequent changes in this bitset will be reflected in the returned immutable bitset. + * + * @return an immutable set containing all the elements of this set. */ def toImmutable = immutable.BitSet.fromArray(elems) @@ -90,8 +108,12 @@ class BitSet(protected var elems: Array[Long]) extends Set[Int] } } +/** $factoryInfo + * @define coll bitset + * @define Coll BitSet + */ object BitSet extends BitSetFactory[BitSet] { def empty: BitSet = new BitSet - /** $canBuildFromInfo */ + /** $bitsetCanBuildFrom */ implicit def canBuildFrom: CanBuildFrom[BitSet, Int, BitSet] = bitsetCanBuildFrom } diff --git a/src/library/scala/collection/mutable/Buffer.scala b/src/library/scala/collection/mutable/Buffer.scala index 1c8aeb6b7a..fbc52ae322 100644 --- a/src/library/scala/collection/mutable/Buffer.scala +++ b/src/library/scala/collection/mutable/Buffer.scala @@ -18,12 +18,17 @@ import generic._ * appending, prepending, or inserting new elements. It is also * possible to access and modify elements in a random access fashion * via the index of the element in the current sequence. - * + * * @author Matthias Zenger * @author Martin Odersky * @version 2.8 * @since 1 - */ + * + * @tparam A type of the elements contained in this buffer. + * + * @define Coll Buffer + * @define coll buffer + */ @cloneable trait Buffer[A] extends Seq[A] with GenericTraversableTemplate[A, Buffer] @@ -31,7 +36,9 @@ trait Buffer[A] extends Seq[A] override def companion: GenericCompanion[Buffer] = Buffer } -/** Factory object for <code>Buffer</code> trait. +/** $factoryInfo + * @define coll buffer + * @define Coll Buffer */ object Buffer extends SeqFactory[Buffer] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Buffer[A]] = new GenericCanBuildFrom[A] diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala index 0fb34cc8e0..15e96b2019 100644 --- a/src/library/scala/collection/mutable/BufferLike.scala +++ b/src/library/scala/collection/mutable/BufferLike.scala @@ -144,8 +144,8 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] */ def append(elems: A*) { appendAll(elems) } - /** Appends the elements contained in a traversable collection to this buffer. - * @param elems the collection containing the elements to append. + /** Appends the elements contained in a traversable object to this buffer. + * @param xs the traversable object containing the elements to append. */ def appendAll(xs: TraversableOnce[A]) { this ++= xs } @@ -154,7 +154,7 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] */ def prepend(elems: A*) { prependAll(elems) } - /** Prepends the elements contained in a traversable collection to this buffer. + /** Prepends the elements contained in a traversable object to this buffer. * @param elems the collection containing the elements to prepend. */ def prependAll(xs: TraversableOnce[A]) { xs ++=: this } @@ -272,7 +272,7 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] /** Adds a number of elements provided by a traversable object and returns * either the collection itself. * - * @param iter the iterable object. + * @param xs the traversable object. */ @migration(2, 8, "As of 2.8, ++ always creates a new collection, even on Buffers.\n"+ diff --git a/src/library/scala/collection/mutable/BufferProxy.scala b/src/library/scala/collection/mutable/BufferProxy.scala index d4444dab67..983572452b 100644 --- a/src/library/scala/collection/mutable/BufferProxy.scala +++ b/src/library/scala/collection/mutable/BufferProxy.scala @@ -16,13 +16,18 @@ import generic._ import script._ /** This is a simple proxy class for <a href="Buffer.html" - * target="contentFrame"><code>scala.collection.mutable.Buffer</code></a>. + * target="contentFrame">`scala.collection.mutable.Buffer`</a>. * It is most useful for assembling customized set abstractions * dynamically using object composition and forwarding. * * @author Matthias Zenger * @version 1.0, 16/04/2004 * @since 1 + * + * @tparam A type of the elements the buffer proxy contains. + * + * @define Coll BufferProxy + * @define coll buffer proxy */ trait BufferProxy[A] extends Buffer[A] with Proxy { @@ -52,21 +57,21 @@ trait BufferProxy[A] extends Buffer[A] with Proxy { override def readOnly = self.readOnly - /** Appends a number of elements provided by an iterable object - * via its <code>iterator</code> method. The identity of the + /** Appends a number of elements provided by a traversable object + * via its <code>foreach</code> method. The identity of the * buffer is returned. * - * @param iter the iterable object. + * @param iter the traversable object. * @return the updated buffer. */ @deprecated("Use ++= instead if you intend to add by side effect to an existing collection.\n"+ "Use `clone() ++=` if you intend to create a new collection.") override def ++(xs: TraversableOnce[A]): Buffer[A] = self.++(xs) - /** Appends a number of elements provided by an iterable object - * via its <code>iterator</code> method. + /** Appends a number of elements provided by a traversable object. * - * @param iter the iterable object. + * @param xs the traversable object. + * @return a reference to this $coll. */ override def ++=(xs: TraversableOnce[A]): this.type = { self.++=(xs); this } @@ -76,10 +81,9 @@ trait BufferProxy[A] extends Buffer[A] with Proxy { */ override def append(elems: A*) { self.++=(elems) } - /** Appends a number of elements provided by an iterable object - * via its <code>iterator</code> method. + /** Appends a number of elements provided by a traversable object. * - * @param iter the iterable object. + * @param xs the traversable object. */ override def appendAll(xs: TraversableOnce[A]) { self.appendAll(xs) } @@ -87,6 +91,7 @@ trait BufferProxy[A] extends Buffer[A] with Proxy { * the identity of the buffer. * * @param elem the element to append. + * @return a reference to this $coll. */ def +=:(elem: A): this.type = { self.+=:(elem); this } @@ -98,26 +103,25 @@ trait BufferProxy[A] extends Buffer[A] with Proxy { */ override def prepend(elems: A*) { self.prependAll(elems) } - /** Prepends a number of elements provided by an iterable object - * via its <code>iterator</code> method. The identity of the - * buffer is returned. + /** Prepends a number of elements provided by a traversable object. + * The identity of the buffer is returned. * - * @param iter the iterable object. + * @param xs the traversable object. */ override def prependAll(xs: TraversableOnce[A]) { self.prependAll(xs) } - /** Inserts new elements at the index <code>n</code>. Opposed to method - * <code>update</code>, this method will not replace an element with a - * one. Instead, it will insert the new elements at index <code>n</code>. + /** Inserts new elements at the index `n`. Opposed to method + * `update`, this method will not replace an element with a + * one. Instead, it will insert the new elements at index `n`. * * @param n the index where a new element will be inserted. * @param elems the new elements to insert. */ override def insert(n: Int, elems: A*) { self.insertAll(n, elems) } - /** Inserts new elements at the index <code>n</code>. Opposed to method - * <code>update</code>, this method will not replace an element with a - * one. Instead, it will insert a new element at index <code>n</code>. + /** Inserts new elements at the index `n`. Opposed to method + * `update`, this method will not replace an element with a + * one. Instead, it will insert a new element at index `n`. * * @param n the index where a new element will be inserted. * @param iter the iterable object providing all elements to insert. @@ -126,8 +130,7 @@ trait BufferProxy[A] extends Buffer[A] with Proxy { override def insertAll(n: Int, iter: scala.collection.Traversable[A]): Unit = self.insertAll(n, iter) - /** Replace element at index <code>n</code> with the new element - * <code>newelem</code>. + /** Replace element at index `n` with the new element `newelem`. * * @param n the index of the element to replace. * @param newelem the new element. @@ -152,7 +155,7 @@ trait BufferProxy[A] extends Buffer[A] with Proxy { /** Return a clone of this buffer. * - * @return a <code>Buffer</code> with the same elements. + * @return a `Buffer` with the same elements. */ override def clone(): Buffer[A] = new BufferProxy[A] { def self = BufferProxy.this.self.clone() diff --git a/src/library/scala/collection/mutable/Builder.scala b/src/library/scala/collection/mutable/Builder.scala index 2e6a9149bc..a930c29948 100644 --- a/src/library/scala/collection/mutable/Builder.scala +++ b/src/library/scala/collection/mutable/Builder.scala @@ -15,7 +15,7 @@ import generic._ /** The base trait of all builders. * A builder lets one construct a collection incrementally, by adding - * elements to the builder with += and then converting to the required + * elements to the builder with `+=` and then converting to the required * collection type with `result`. * * @tparam Elem the type of elements that get added to the builder. diff --git a/src/library/scala/collection/mutable/Cloneable.scala b/src/library/scala/collection/mutable/Cloneable.scala index 34e0548cb8..099c6a68b4 100644 --- a/src/library/scala/collection/mutable/Cloneable.scala +++ b/src/library/scala/collection/mutable/Cloneable.scala @@ -14,7 +14,9 @@ package mutable /** A trait for cloneable collections. * - * @since 2.8 + * @since 2.8 + * + * @tparam A Type of the elements contained in the collection, covariant and with reference types as upperbound. */ @cloneable trait Cloneable[+A <: AnyRef] { diff --git a/src/library/scala/collection/mutable/CloneableCollection.scala b/src/library/scala/collection/mutable/CloneableCollection.scala index f859b9e82b..a88d85965f 100644 --- a/src/library/scala/collection/mutable/CloneableCollection.scala +++ b/src/library/scala/collection/mutable/CloneableCollection.scala @@ -12,8 +12,8 @@ package scala.collection package mutable -/** The J2ME version of the library defined this trait with a <code>clone</code> - * method to substitute for the lack of <code>Object.clone</code> there. +/** The J2ME version of the library defined this trait with a `clone` + * method to substitute for the lack of `Object.clone` there. * * @since 2.6 */ diff --git a/src/library/scala/collection/mutable/ConcurrentMap.scala b/src/library/scala/collection/mutable/ConcurrentMap.scala index 2cfa4f8ae2..f9505f694b 100644 --- a/src/library/scala/collection/mutable/ConcurrentMap.scala +++ b/src/library/scala/collection/mutable/ConcurrentMap.scala @@ -1,23 +1,26 @@ package scala.collection package mutable -/** - * A template trait for mutable maps that allow concurrent access. - * $concurrentmapinfo + +/** A template trait for mutable maps that allow concurrent access. + * + * $concurrentmapinfo * - * @tparam A the key type of the map - * @tparam B the value type of the map + * @since 2.8 * - * @define concurrentmapinfo - * This is a base trait for all Scala concurrent map implementations. It - * provides all of the methods a Map does, with the difference that all the - * changes are atomic. It also describes methods specific to concurrent maps. - * Note: The concurrent maps do not accept `null` for keys or values. + * @tparam A the key type of the map + * @tparam B the value type of the map * - * @define atomicop - * This is done atomically. + * @define Coll ConcurrentMap + * @define coll concurrent map + * @define concurrentmapinfo + * This is a base trait for all Scala concurrent map implementations. It + * provides all of the methods a `Map` does, with the difference that all the + * changes are atomic. It also describes methods specific to concurrent maps. + * Note: The concurrent maps do not accept `null` for keys or values. * - * @since 2.8 + * @define atomicop + * This is done atomically. */ trait ConcurrentMap[A, B] extends Map[A, B] { diff --git a/src/library/scala/collection/mutable/DefaultEntry.scala b/src/library/scala/collection/mutable/DefaultEntry.scala index 6071efcb9a..553fb3c678 100644 --- a/src/library/scala/collection/mutable/DefaultEntry.scala +++ b/src/library/scala/collection/mutable/DefaultEntry.scala @@ -12,8 +12,10 @@ package scala.collection package mutable -/** - * @since 2.3 + + +/** Class used internally for default map model. + * @since 2.3 */ @serializable final class DefaultEntry[A, B](val key: A, var value: B) diff --git a/src/library/scala/collection/mutable/DefaultMapModel.scala b/src/library/scala/collection/mutable/DefaultMapModel.scala index fbe46e2a72..d22b20e10c 100644 --- a/src/library/scala/collection/mutable/DefaultMapModel.scala +++ b/src/library/scala/collection/mutable/DefaultMapModel.scala @@ -12,9 +12,8 @@ package scala.collection package mutable -/** This class is used internally. It implements the mutable <code>Map</code> - * class in terms of three functions: <code>findEntry</code>, - * <code>addEntry</code>, and <code>entries</code>. +/** This class is used internally. It implements the mutable `Map` + * class in terms of three functions: `findEntry`, `addEntry`, and `entries`. * * @author Matthias Zenger * @version 1.0, 08/07/2003 diff --git a/src/library/scala/collection/mutable/DoubleLinkedList.scala b/src/library/scala/collection/mutable/DoubleLinkedList.scala index 718d6aa35d..d8b8278c74 100644 --- a/src/library/scala/collection/mutable/DoubleLinkedList.scala +++ b/src/library/scala/collection/mutable/DoubleLinkedList.scala @@ -14,13 +14,29 @@ package mutable import generic._ -/** This class implements double linked lists where both the head (<code>elem</code>) - * and the tail (<code>next</code>) are mutable. +/** This class implements double linked lists where both the head (`elem`), + * the tail (`next`) and a reference to the previous node (`prev`) are mutable. * * @author Matthias Zenger * @author Martin Odersky * @version 2.8 * @since 1 + * + * @tparam A the type of the elements contained in this double linked list. + * + * @define Coll DoubleLinkedList + * @define coll double linked list + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `DoubleLinkedList[B]` because an implicit of type `CanBuildFrom[DoubleLinkedList, B, DoubleLinkedList[B]]` + * is defined in object `DoubleLinkedList`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `DoubleLinkedList`. + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @serializable @SerialVersionUID(-8144992287952814767L) class DoubleLinkedList[A]() extends LinearSeq[A] @@ -28,6 +44,11 @@ class DoubleLinkedList[A]() extends LinearSeq[A] with DoubleLinkedListLike[A, DoubleLinkedList[A]] { next = this + /** Creates a node for the double linked list. + * + * @param elem the element this node contains. + * @param next the next node in the double linked list. + */ def this(elem: A, next: DoubleLinkedList[A]) { this() if (next != null) { @@ -39,7 +60,12 @@ class DoubleLinkedList[A]() extends LinearSeq[A] override def companion: GenericCompanion[DoubleLinkedList] = DoubleLinkedList } +/** $factoryInfo + * @define coll double linked list + * @define Coll DoubleLinkedList + */ object DoubleLinkedList extends SeqFactory[DoubleLinkedList] { + /** $genericCanBuildFrom */ implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, DoubleLinkedList[A]] = new GenericCanBuildFrom[A] def newBuilder[A]: Builder[A, DoubleLinkedList[A]] = new Builder[A, DoubleLinkedList[A]] { diff --git a/src/library/scala/collection/mutable/DoubleLinkedListLike.scala b/src/library/scala/collection/mutable/DoubleLinkedListLike.scala index 269d1997d0..b908a1802b 100644 --- a/src/library/scala/collection/mutable/DoubleLinkedListLike.scala +++ b/src/library/scala/collection/mutable/DoubleLinkedListLike.scala @@ -13,16 +13,23 @@ package scala.collection package mutable /** This extensible class may be used as a basis for implementing double - * linked lists. Type variable <code>A</code> refers to the element type - * of the list, type variable <code>This</code> is used to model self + * linked lists. Type variable `A` refers to the element type + * of the list, type variable `This` is used to model self * types of linked lists. * * @author Matthias Zenger * @version 1.0, 08/07/2003 * @since 2.8 + * + * @tparam A type of the elements contained in the double linked list + * @tparam This the type of the actual linked list holding the elements + * + * @define Coll DoubleLinkedList + * @define coll double linked list */ trait DoubleLinkedListLike[A, This <: Seq[A] with DoubleLinkedListLike[A, This]] extends LinkedListLike[A, This] { self => + /** A reference to the node in the linked list preceeding the current node. */ var prev: This = _ override def append(that: This): This = diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala index ea4033d405..05eafbc811 100644 --- a/src/library/scala/collection/mutable/FlatHashTable.scala +++ b/src/library/scala/collection/mutable/FlatHashTable.scala @@ -11,8 +11,15 @@ package scala.collection package mutable -/** An implementation class backing a HashSet. - * @since 2.3 + +/** An implementation class backing a `HashSet`. + * + * This trait is used internally. It can be mixed in with various collections relying on + * hash table as an implementation. + * + * @since 2.3 + * + * @tparam A the type of the elements contained in the flat hash table. */ trait FlatHashTable[A] { @@ -85,6 +92,7 @@ trait FlatHashTable[A] { iterator.foreach(out.writeObject) } + /** Finds an entry in the hash table if such an element exists. */ def findEntry(elem: A): Option[A] = { var h = index(elemHashCode(elem)) var entry = table(h) @@ -95,6 +103,7 @@ trait FlatHashTable[A] { if (null == entry) None else Some(entry.asInstanceOf[A]) } + /** Checks whether an element is contained in the hash table. */ def containsEntry(elem: A): Boolean = { var h = index(elemHashCode(elem)) var entry = table(h) @@ -105,8 +114,8 @@ trait FlatHashTable[A] { null != entry } - /** Add entry if not yet in table - * Return whether a new entry was added + /** Add entry if not yet in table. + * @return Returns `true` if a new entry was added, `false` otherwise. */ def addEntry(elem: A) : Boolean = { var h = index(elemHashCode(elem)) @@ -122,6 +131,7 @@ trait FlatHashTable[A] { true } + /** 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] = { if (tableDebug) checkConsistent() def precedes(i: Int, j: Int) = { diff --git a/src/library/scala/collection/mutable/GrowingBuilder.scala b/src/library/scala/collection/mutable/GrowingBuilder.scala index 445e9d4f3e..cd1c8bec8c 100644 --- a/src/library/scala/collection/mutable/GrowingBuilder.scala +++ b/src/library/scala/collection/mutable/GrowingBuilder.scala @@ -13,14 +13,17 @@ import generic._ /** The canonical builder for collections that are growable, i.e. that support an * efficient `+=` method which adds an element to the collection. It is - * almost identical to AddingBuilder, but necessitated by the existence of - * classes which are Growable but not Addable, which is a result of covariance - * interacting surprisingly with any2stringadd thus driving '+' out of the Seq + * almost identical to `AddingBuilder`, but necessitated by the existence of + * classes which are `Growable` but not `Addable`, which is a result of covariance + * interacting surprisingly with any2stringadd thus driving '+' out of the `Seq` * hierarchy. The tendrils of original sin should never be underestimated. * * @author Paul Phillips * @version 2.8 * @since 2.8 + * + * @define Coll GrowingBuilder + * @define coll growing builder */ class GrowingBuilder[Elem, To <: Growable[Elem]](empty: To) extends Builder[Elem, To] { protected var elems: To = empty diff --git a/src/library/scala/collection/mutable/HashEntry.scala b/src/library/scala/collection/mutable/HashEntry.scala index 3373913412..7c62dc6281 100644 --- a/src/library/scala/collection/mutable/HashEntry.scala +++ b/src/library/scala/collection/mutable/HashEntry.scala @@ -8,8 +8,8 @@ package scala.collection package mutable -/** - * @since 2.8 +/** Class used internally. + * @since 2.8 */ trait HashEntry [A, E] { val key: A diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala index 2b5cad37d8..215e0323b3 100644 --- a/src/library/scala/collection/mutable/HashMap.scala +++ b/src/library/scala/collection/mutable/HashMap.scala @@ -14,8 +14,27 @@ package mutable import generic._ -/** - * @since 1 + +/** This class implements mutable maps using a hashtable. + * + * @since 1 + * + * @tparam A the type of the keys contained in this hash map. + * @tparam B the type of the values assigned to keys in this hash map. + * + * @define Coll mutable.HashMap + * @define coll mutable hash map + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `HashMap[A, B]` if the elements contained in the resulting collection are + * pairs of type `(A, B)`. This is because an implicit of type `CanBuildFrom[HashMap, (A, B), HashMap[A, B]]` + * is defined in object `HashMap`. Otherwise, `That` resolves to the most specific type that doesn't have + * to contain pairs of type `(A, B)`, which is `Iterable`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `HashMap`. + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @serializable @SerialVersionUID(1L) class HashMap[A, B] extends Map[A, B] @@ -94,11 +113,9 @@ class HashMap[A, B] extends Map[A, B] } } -/** This class implements mutable maps using a hashtable. - * - * @author Matthias Zenger - * @author Martin Odersky - * @version 2.8 +/** $factoryInfo + * @define Coll mutable.HashMap + * @define coll mutable hash map */ object HashMap extends MutableMapFactory[HashMap] { implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), HashMap[A, B]] = new MapCanBuildFrom[A, B] diff --git a/src/library/scala/collection/mutable/HashSet.scala b/src/library/scala/collection/mutable/HashSet.scala index e985e717b0..3d9dc3e55d 100644 --- a/src/library/scala/collection/mutable/HashSet.scala +++ b/src/library/scala/collection/mutable/HashSet.scala @@ -20,6 +20,20 @@ import generic._ * @author Martin Odersky * @version 2.0, 31/12/2006 * @since 1 + * + * @tparam A the type of the elements contained in this set. + * + * @define Coll mutable.HashSet + * @define coll mutable hash set + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `HashSet[B]` because an implicit of type `CanBuildFrom[HashSet, B, HashSet[B]]` + * is defined in object `HashSet`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `HashSet`. + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @serializable @SerialVersionUID(1L) class HashSet[A] extends Set[A] @@ -61,7 +75,10 @@ class HashSet[A] extends Set[A] } } -/** Factory object for `HashSet` class */ +/** $factoryInfo + * @define Coll mutable.HashSet + * @define coll mutable hash set + */ object HashSet extends SetFactory[HashSet] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, HashSet[A]] = setCanBuildFrom[A] override def empty[A]: HashSet[A] = new HashSet[A] diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index 14f1720a4c..04b5e5e3a1 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -13,22 +13,24 @@ package scala.collection package mutable /** This class can be used to construct data structures that are based - * on hashtables. Class <code>HashTable[A]</code> implements a hashtable - * that maps keys of type <code>A</code> to values of the fully abstract - * member type <code>Entry</code>. Classes that make use of <code>HashTable</code> - * have to provide an implementation for <code>Entry</code> + * on hashtables. Class `HashTable[A]` implements a hashtable + * that maps keys of type `A` to values of the fully abstract + * member type `Entry`. Classes that make use of `HashTable` + * have to provide an implementation for `Entry`. * * There are mainly two parameters that affect the performance of a hashtable: * the <i>initial size</i> and the <i>load factor</i>. The <i>size</i> * refers to the number of <i>buckets</i> in the hashtable, and the <i>load * factor</i> is a measure of how full the hashtable is allowed to get before * its size is automatically doubled. Both parameters may be changed by - * overriding the corresponding values in class <code>HashTable</code>. + * overriding the corresponding values in class `HashTable`. * * @author Matthias Zenger * @author Martin Odersky * @version 2.0, 31/12/2006 * @since 1 + * + * @tparam A type of the elements contained in this hash table. */ trait HashTable[A] { import HashTable._ @@ -108,7 +110,7 @@ trait HashTable[A] { private def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize) - /** Find entry with given key in table, null if not found + /** Find entry with given key in table, null if not found. */ protected def findEntry(key: A): Entry = { val h = index(elemHashCode(key)) @@ -129,7 +131,7 @@ trait HashTable[A] { resize(2 * table.length) } - /** Remove entry from table if present + /** Remove entry from table if present. */ protected def removeEntry(key: A) : Entry = { val h = index(elemHashCode(key)) @@ -155,7 +157,7 @@ trait HashTable[A] { null } - /** An iterator returning all entries + /** An iterator returning all entries. */ protected def entriesIterator: Iterator[Entry] = new Iterator[Entry] { val iterTable = table diff --git a/src/library/scala/collection/mutable/History.scala b/src/library/scala/collection/mutable/History.scala index 40ebfe5fa5..ffa3d6481a 100644 --- a/src/library/scala/collection/mutable/History.scala +++ b/src/library/scala/collection/mutable/History.scala @@ -13,14 +13,17 @@ package scala.collection package mutable -/** <code>History[A, B]</code> objects may subscribe to events of - * type <code>A</code> published by an object of type <code>B</code>. +/** `History[A, B]` objects may subscribe to events of + * type `A` published by an object of type `B`. * The history subscriber object records all published events - * up to maximum number of <code>maxHistory</code> events. + * up to maximum number of `maxHistory` events. * * @author Matthias Zenger * @version 1.0, 08/07/2003 * @since 1 + * + * @tparam Evt Type of events. + * @tparam Pub Type of publishers. */ @serializable @SerialVersionUID(5219213543849892588L) @@ -29,9 +32,10 @@ class History[Evt, Pub] extends Subscriber[Evt, Pub] with Iterable[(Pub, Evt)] protected val log: Queue[(Pub, Evt)] = new Queue val maxHistory: Int = 1000 - /** - * @param pub ... - * @param event ... + /** Notifies this listener with an event by enqueuing it in the log. + * + * @param pub the publisher. + * @param event the event. */ def notify(pub: Pub, event: Evt) { if (log.length >= maxHistory) diff --git a/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala b/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala index fba28e7c2a..c2b7cfd2b8 100644 --- a/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala +++ b/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala @@ -15,9 +15,9 @@ package mutable import annotation.migration /** This class can be used as an adaptor to create mutable maps from - * immutable map implementations. Only method <code>empty</code> has + * immutable map implementations. Only method `empty` has * to be redefined if the immutable map on which this mutable map is - * originally based is not empty. <code>empty</code> is supposed to + * originally based is not empty. `empty` is supposed to * return the representation of an empty map. * * @author Matthias Zenger diff --git a/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala b/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala index 5b0ed17788..a56f65e379 100644 --- a/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala +++ b/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala @@ -14,9 +14,9 @@ package mutable /** This class can be used as an adaptor to create mutable sets from - * immutable set implementations. Only method <code>empty</code> has + * immutable set implementations. Only method `empty` has * to be redefined if the immutable set on which this mutable set is - * originally based is not empty. <code>empty</code> is supposed to + * originally based is not empty. `empty` is supposed to * return the representation of an empty set. * * @author Matthias Zenger diff --git a/src/library/scala/collection/mutable/IndexedSeq.scala b/src/library/scala/collection/mutable/IndexedSeq.scala index 0a173395e0..14ee5afc9b 100644 --- a/src/library/scala/collection/mutable/IndexedSeq.scala +++ b/src/library/scala/collection/mutable/IndexedSeq.scala @@ -14,11 +14,10 @@ package mutable import generic._ -/** A subtrait of <code>collection.IndexedSeq</code> which represents sequences +/** A subtrait of `collection.IndexedSeq` which represents sequences * that can be mutated. - * $indexedSeqInfo * - * @since 2.8 + * $indexedSeqInfo */ trait IndexedSeq[A] extends Seq[A] with scala.collection.IndexedSeq[A] @@ -27,6 +26,10 @@ trait IndexedSeq[A] extends Seq[A] override def companion: GenericCompanion[IndexedSeq] = IndexedSeq } +/** $factoryInfo + * @define coll indexed sequence + * @define Coll IndexedSeq + */ object IndexedSeq extends SeqFactory[IndexedSeq] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, IndexedSeq[A]] = new GenericCanBuildFrom[A] def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer[A] diff --git a/src/library/scala/collection/mutable/IndexedSeqLike.scala b/src/library/scala/collection/mutable/IndexedSeqLike.scala index a0f9205da2..0c2d3f17bb 100644 --- a/src/library/scala/collection/mutable/IndexedSeqLike.scala +++ b/src/library/scala/collection/mutable/IndexedSeqLike.scala @@ -16,7 +16,26 @@ import generic._ /** A subtrait of scala.collection.IndexedSeq which represents sequences * that can be mutated. * - * @since 2.8 + * It declares a method `update` which allows updating an element + * at a specific index in the sequence. + * + * This trait just implements `iterator` in terms of `apply` and `length`. + * However, see `IndexedSeqOptimized` for an implementation trait that overrides operations + * to make them run faster under the assumption of fast random access with `apply`. + * + * $indexedSeqInfo + * + * @tparam A the element type of the $coll + * @tparam Repr the type of the actual $coll containing the elements. + * + * @define Coll IndexedSeq + * @define coll mutable indexed sequence + * @define indexedSeqInfo + * @author Martin Odersky + * @version 2.8 + * @since 2.8 + * @define willNotTerminateInf + * @define mayNotTerminateInf */ trait IndexedSeqLike[A, +Repr] extends scala.collection.IndexedSeqLike[A, Repr] { self => diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala index d870b762d3..9a0e7a4010 100644 --- a/src/library/scala/collection/mutable/IndexedSeqView.scala +++ b/src/library/scala/collection/mutable/IndexedSeqView.scala @@ -92,6 +92,8 @@ self => } /** $factoryInfo + * @define coll indexed sequence view + * @define Coll IndexedSeqView * Note that the canBuildFrom factories yield SeqViews, not IndexedSewqViews. * This is intentional, because not all operations yield again a mutable.IndexedSeqView. * For instance, map just gives a SeqView, which reflects the fact that diff --git a/src/library/scala/collection/mutable/Iterable.scala b/src/library/scala/collection/mutable/Iterable.scala index 347ee3c8ac..85c6df6fb0 100644 --- a/src/library/scala/collection/mutable/Iterable.scala +++ b/src/library/scala/collection/mutable/Iterable.scala @@ -10,15 +10,8 @@ package mutable import generic._ -/** <p> - * A subtrait of <a href="../Iterable.html" target="contentFrame"> - * <code>collection.Iterable</code></a> which represents iterables - * that can be mutated. - * </p> - * - * @author Martin Odersky - * @version 2.8 - * @since 2.8 +/** A base trait for iterable collections that can be mutated. + * $iterableInfo */ trait Iterable[A] extends Traversable[A] with scala.collection.Iterable[A] @@ -27,13 +20,9 @@ trait Iterable[A] extends Traversable[A] override def companion: GenericCompanion[Iterable] = Iterable } -/** <p> - * A factory object for the trait <a href="Iterable.html" - * target="contentFrame"><code>Iterable</code></a>. - * </p> - * - * @author Martin Odersky - * @version 2.8 +/** $factoryInfo + * @define coll indexed sequence + * @define Coll IndexedSeq */ object Iterable extends TraversableFactory[Iterable] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Iterable[A]] = new GenericCanBuildFrom[A] diff --git a/src/library/scala/collection/mutable/LazyBuilder.scala b/src/library/scala/collection/mutable/LazyBuilder.scala index 7714d29f08..91cf8f2ad9 100644 --- a/src/library/scala/collection/mutable/LazyBuilder.scala +++ b/src/library/scala/collection/mutable/LazyBuilder.scala @@ -17,6 +17,9 @@ import immutable.{List, Nil} * be added to this builder with `++=` are not evaluated until `result` is called. * * @since 2.8 + * + * @tparam Elem type of the elements for this builder. + * @tparam To type of the collection this builder builds. */ abstract class LazyBuilder[Elem, +To] extends Builder[Elem, To] { /** The different segments of elements to be added to the builder, represented as iterators */ diff --git a/src/library/scala/collection/mutable/LinearSeq.scala b/src/library/scala/collection/mutable/LinearSeq.scala index 9abaef5aff..185b8c97a3 100644 --- a/src/library/scala/collection/mutable/LinearSeq.scala +++ b/src/library/scala/collection/mutable/LinearSeq.scala @@ -14,11 +14,12 @@ package mutable import generic._ -/** A subtrait of <code>collection.LinearSeq</code> which represents sequences +/** A subtrait of `collection.LinearSeq` which represents sequences * that can be mutated. * $linearSeqInfo * - * @since 2.8 + * @define Coll LinearSeq + * @define coll linear sequence */ trait LinearSeq[A] extends Seq[A] with scala.collection.LinearSeq[A] @@ -27,6 +28,10 @@ trait LinearSeq[A] extends Seq[A] override def companion: GenericCompanion[LinearSeq] = LinearSeq } +/** $factoryInfo + * @define coll linear sequence + * @define Coll LinearSeq + */ object LinearSeq extends SeqFactory[LinearSeq] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, LinearSeq[A]] = new GenericCanBuildFrom[A] def newBuilder[A]: Builder[A, LinearSeq[A]] = new MutableList[A] diff --git a/src/library/scala/collection/mutable/LinkedEntry.scala b/src/library/scala/collection/mutable/LinkedEntry.scala index 46db4cdf09..5d591058e8 100644 --- a/src/library/scala/collection/mutable/LinkedEntry.scala +++ b/src/library/scala/collection/mutable/LinkedEntry.scala @@ -12,8 +12,8 @@ package scala.collection package mutable -/** - * @since 2.8 +/** Class for the linked hash map entry, used internally. + * @since 2.8 */ @serializable final class LinkedEntry[A, B](val key: A, var value: B) diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala index 2636219727..97961ccd9c 100644 --- a/src/library/scala/collection/mutable/LinkedHashMap.scala +++ b/src/library/scala/collection/mutable/LinkedHashMap.scala @@ -14,20 +14,36 @@ package mutable import generic._ -/** This class implements mutable maps using a hashtable. - * The iterator and all traversal methods of this class visit elements in the order they were inserted. - * - * @author Martin Odersky - * @version 2.8 - * @since 2.7 +/** $factoryInfo + * @define Coll LinkedHashMap + * @define coll linked hash map */ object LinkedHashMap extends MutableMapFactory[LinkedHashMap] { implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), LinkedHashMap[A, B]] = new MapCanBuildFrom[A, B] def empty[A, B] = new LinkedHashMap[A, B] } -/** - * @since 2.7 +/** This class implements mutable maps using a hashtable. + * The iterator and all traversal methods of this class visit elements in the order they were inserted. + * + * @tparam A the type of the keys contained in this hash map. + * @tparam B the type of the values assigned to keys in this hash map. + * + * @define Coll LinkedHashMap + * @define coll linked hash map + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `LinkedHashMap[A, B]` if the elements contained in the resulting collection are + * pairs of type `(A, B)`. This is because an implicit of type `CanBuildFrom[LinkedHashMap, (A, B), LinkedHashMap[A, B]]` + * is defined in object `LinkedHashMap`. Otherwise, `That` resolves to the most specific type that doesn't have + * to contain pairs of type `(A, B)`, which is `Iterable`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `LinkedHashMap`. + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define orderDependent + * @define orderDependentFold */ @serializable @SerialVersionUID(1L) class LinkedHashMap[A, B] extends Map[A, B] diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index 54338f61c9..7ecb71e23b 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -13,9 +13,29 @@ package mutable import generic._ -/** Todo: this has O(n) cost for element removal. - * Should be rewritten to be more efficient. - * @since 2.2 +/** This class implements mutable sets using a hashtable. + * The iterator and all traversal methods of this class visit elements in the order they were inserted. + * + * @author Matthias Zenger + * @author Martin Odersky + * @version 2.0, 31/12/2006 + * @since 1 + * + * @tparam A the type of the elements contained in this set. + * + * @define Coll LinkedHashSet + * @define coll linked hash set + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `LinkedHashSet[B]` because an implicit of type `CanBuildFrom[LinkedHashSet, B, LinkedHashSet[B]]` + * is defined in object `LinkedHashSet`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `LinkedHashSet`. + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define orderDependent + * @define orderDependentFold */ @serializable @SerialVersionUID(1L) class LinkedHashSet[A] extends Set[A] @@ -63,7 +83,10 @@ class LinkedHashSet[A] extends Set[A] } } -/** Factory object for `LinkedHashSet` class */ +/** $factoryInfo + * @define Coll LinkedHashSet + * @define coll linked hash set + */ object LinkedHashSet extends SetFactory[LinkedHashSet] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, LinkedHashSet[A]] = setCanBuildFrom[A] override def empty[A]: LinkedHashSet[A] = new LinkedHashSet[A] diff --git a/src/library/scala/collection/mutable/LinkedList.scala b/src/library/scala/collection/mutable/LinkedList.scala index 5570e80b22..a72acf1438 100644 --- a/src/library/scala/collection/mutable/LinkedList.scala +++ b/src/library/scala/collection/mutable/LinkedList.scala @@ -14,13 +14,29 @@ package mutable import generic._ -/** This class implements single linked lists where both the head (<code>elem</code>) - * and the tail (<code>next</code>) are mutable. +/** This class implements single linked lists where both the head (`elem`) + * and the tail (`next`) are mutable. * * @author Matthias Zenger * @author Martin Odersky * @version 2.8 * @since 1 + * + * @tparam A the type of the elements contained in this linked list. + * + * @define Coll LinkedList + * @define coll linked list + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `LinkedList[B]` because an implicit of type `CanBuildFrom[LinkedList, B, LinkedList[B]]` + * is defined in object `LinkedList`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `LinkedList`. + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @serializable @SerialVersionUID(-7308240733518833071L) class LinkedList[A]() extends LinearSeq[A] @@ -39,6 +55,10 @@ class LinkedList[A]() extends LinearSeq[A] override def companion: GenericCompanion[LinkedList] = LinkedList } +/** $factoryInfo + * @define Coll LinkedList + * @define coll linked list + */ object LinkedList extends SeqFactory[LinkedList] { override def empty[A]: LinkedList[A] = new LinkedList[A] diff --git a/src/library/scala/collection/mutable/LinkedListLike.scala b/src/library/scala/collection/mutable/LinkedListLike.scala index 2523ece370..4f1a878e02 100644 --- a/src/library/scala/collection/mutable/LinkedListLike.scala +++ b/src/library/scala/collection/mutable/LinkedListLike.scala @@ -16,13 +16,20 @@ import generic._ import annotation.tailrec /** This extensible class may be used as a basis for implementing linked - * list. Type variable <code>A</code> refers to the element type of the - * list, type variable <code>This</code> is used to model self types of + * list. Type variable `A` refers to the element type of the + * list, type variable `This` is used to model self types of * linked lists. + * * @author Matthias Zenger * @author Martin Odersky - * @version 2.8 + * @version 1.0, 08/07/2003 * @since 2.8 + * + * @tparam A type of the elements contained in the linked list + * @tparam This the type of the actual linked list holding the elements + * + * @define Coll LinkedList + * @define coll linked list */ trait LinkedListLike[A, This <: Seq[A] with LinkedListLike[A, This]] extends SeqLike[A, This] { self => diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index b8e5aeb262..a2611a8c0f 100644 --- a/src/library/scala/collection/mutable/ListBuffer.scala +++ b/src/library/scala/collection/mutable/ListBuffer.scala @@ -15,13 +15,29 @@ package mutable import generic._ import immutable.{List, Nil, ::} -/** A Buffer implementation back up by a list. It provides constant time +/** A `Buffer` implementation back up by a list. It provides constant time * prepend and append. Most other operations are linear. * * @author Matthias Zenger * @author Martin Odersky * @version 2.8 * @since 1 + * + * @tparam A the type of this list buffer's elements. + * + * @define Coll ListBuffer + * @define coll list buffer + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `ListBuffer[B]` because an implicit of type `CanBuildFrom[ListBuffer, B, ListBuffer[B]]` + * is defined in object `ListBuffer`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `ListBuffer`. + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf */ @serializable @SerialVersionUID(3419063961353022661L) final class ListBuffer[A] @@ -42,7 +58,9 @@ final class ListBuffer[A] protected def underlying: immutable.Seq[A] = start - /** The current length of the buffer + /** The current length of the buffer. + * + * This operation takes constant time. */ override def length = len @@ -52,13 +70,13 @@ final class ListBuffer[A] if (n < 0 || n >= len) throw new IndexOutOfBoundsException(n.toString()) else super.apply(n) - /** Replaces element at index <code>n</code> with the new element - * <code>newelem</code>. Takes time linear in the buffer size. (except the + /** Replaces element at index `n` with the new element + * `newelem`. Takes time linear in the buffer size. (except the * first element, which is updated in constant time). * * @param n the index of the element to replace. * @param x the new element. - * @throws Predef.IndexOutOfBoundsException if <code>n</code> is out of bounds. + * @throws Predef.IndexOutOfBoundsException if `n` is out of bounds. */ def update(n: Int, x: A) { try { @@ -90,6 +108,7 @@ final class ListBuffer[A] /** Appends a single element to this buffer. This operation takes constant time. * * @param x the element to append. + * @return this $coll. */ def += (x: A): this.type = { if (exported) copy() @@ -117,7 +136,7 @@ final class ListBuffer[A] * time. * * @param x the element to prepend. - * @return this buffer. + * @return this $coll. */ def +=: (x: A): this.type = { if (exported) copy() @@ -128,13 +147,13 @@ final class ListBuffer[A] this } - /** Inserts new elements at the index <code>n</code>. Opposed to method - * <code>update</code>, this method will not replace an element with a new - * one. Instead, it will insert a new element at index <code>n</code>. + /** Inserts new elements at the index `n`. Opposed to method + * `update`, this method will not replace an element with a new + * one. Instead, it will insert a new element at index `n`. * * @param n the index where a new element will be inserted. * @param iter the iterable object providing all elements to insert. - * @throws Predef.IndexOutOfBoundsException if <code>n</code> is out of bounds. + * @throws Predef.IndexOutOfBoundsException if `n` is out of bounds. */ def insertAll(n: Int, seq: Traversable[A]) { try { @@ -230,9 +249,9 @@ final class ListBuffer[A] * the buffer size * * @param n the index which refers to the element to delete. - * @return n the element that was formerly at position <code>n</code>. - * @note an element must exists at position <code>n</code> - * @throws Predef.IndexOutOfBoundsException if <code>n</code> is out of bounds. + * @return n the element that was formerly at position `n`. + * @note an element must exists at position `n`. + * @throws Predef.IndexOutOfBoundsException if `n` is out of bounds. */ def remove(n: Int): A = { if (n < 0 || n >= len) throw new IndexOutOfBoundsException(n.toString()) @@ -259,6 +278,7 @@ final class ListBuffer[A] * buffer size. * * @param x the element to remove. + * @return this $coll. */ override def -= (elem: A): this.type = { if (exported) copy() @@ -328,10 +348,9 @@ final class ListBuffer[A] override def stringPrefix: String = "ListBuffer" } -/** Factory object for <code>ListBuffer</code> class. - * - * @author Martin Odersky - * @version 2.8 +/** $factoryInfo + * @define Coll ListBuffer + * @define coll list buffer */ object ListBuffer extends SeqFactory[ListBuffer] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, ListBuffer[A]] = new GenericCanBuildFrom[A] diff --git a/src/library/scala/collection/mutable/ListMap.scala b/src/library/scala/collection/mutable/ListMap.scala index c96873c81d..a4321d3818 100644 --- a/src/library/scala/collection/mutable/ListMap.scala +++ b/src/library/scala/collection/mutable/ListMap.scala @@ -14,8 +14,26 @@ package mutable import generic._ -/** A simple map backed by a list. - * @since 2.8 +/** A simple mutable map backed by a list. + * + * @tparam A the type of the keys contained in this list map. + * @tparam B the type of the values assigned to keys in this list map. + * + * @define Coll mutable.ListMap + * @define coll mutable list map + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is always `ListMap[A, B]` if the elements contained in the resulting collection are + * pairs of type `(A, B)`. This is because an implicit of type `CanBuildFrom[ListMap, (A, B), ListMap[A, B]]` + * is defined in object `ListMap`. Otherwise, `That` resolves to the most specific type that doesn't have + * to contain pairs of type `(A, B)`, which is `Iterable`. + * @define $bfinfo an implicit value of class `CanBuildFrom` which determines the + * result class `That` from the current representation type `Repr` + * and the new element type `B`. This is usually the `canBuildFrom` value + * defined in object `ListMap`. + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define orderDependent + * @define orderDependentFold */ @serializable class ListMap[A, B] extends Map[A, B] with MapLike[A, B, ListMap[A, B]] { @@ -40,10 +58,9 @@ class ListMap[A, B] extends Map[A, B] with MapLike[A, B, ListMap[A, B]] { override def size: Int = siz } -/** This class implements mutable maps using a list. - * - * @author Martin Odersky - * @version 2.8 +/** $factoryInfo + * @define Coll ListMap + * @define coll list map */ object ListMap extends MutableMapFactory[ListMap] { implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), ListMap[A, B]] = new MapCanBuildFrom[A, B] diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala index 9c3c1c0e5f..19e67a6731 100644 --- a/src/library/scala/collection/mutable/MapLike.scala +++ b/src/library/scala/collection/mutable/MapLike.scala @@ -40,7 +40,7 @@ import annotation.migration * `drop`, `filter` return the same kind of map, you * should also override: * {{{ - * def> empty: This + * def empty: This * }}} * If you wish to avoid the unnecessary construction of an `Option` * object, you could also override `apply`, `update`, @@ -187,7 +187,8 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]] */ def clear() { keysIterator foreach -= } - /** If given key is already in this map, returns associated value + /** If given key is already in this map, returns associated value. + * * Otherwise, computes value from given expression `op`, stores with key * in map and returns that value. * @param key the key to test diff --git a/src/library/scala/collection/mutable/MultiMap.scala b/src/library/scala/collection/mutable/MultiMap.scala index 01ddea070c..39c51ef5ad 100644 --- a/src/library/scala/collection/mutable/MultiMap.scala +++ b/src/library/scala/collection/mutable/MultiMap.scala @@ -13,21 +13,42 @@ package scala.collection package mutable -/** This class is typically used as a mixin. It turns maps which map <code>A</code> - * to <code>Set[B]</code> objects into multi maps which map <code>A</code> to - * <code>B</code> objects. +/** A trait for mutable maps with multiple values assigned to a key. * + * This class is typically used as a mixin. It turns maps which map `A` + * to `Set[B]` objects into multi maps which map `A` to + * `B` objects. + * + * @define coll multimap + * @define Coll MultiMap * @author Matthias Zenger * @author Martin Odersky * @version 2.8 * @since 1 */ trait MultiMap[A, B] extends Map[A, Set[B]] { + /** Creates a new set. + * + * Classes that use this trait as a mixin can override this method + * to have the desired implementation of sets assigned to new keys. + * By default this is `HashSet`. + * + * @return An empty set of values of type `B`. + */ protected def makeSet: Set[B] = new HashSet[B] @deprecated("use addBinding instead") def add(key: A, value: B): this.type = addBinding(key, value) + /** Assigns the specified `value` to a specified `key`, replacing + * the existing value assigned to that `key` if it is equal to + * the specified value. Otherwise, simply adds another binding to + * the `key`. + * + * @param key The key to which to bind the new value. + * @param value The value to bind to the key. + * @return A reference to this multimap. + */ def addBinding(key: A, value: B): this.type = { get(key) match { case None => @@ -40,6 +61,15 @@ trait MultiMap[A, B] extends Map[A, Set[B]] { this } + /** Removes the binding of `value` to `key` if it exists. + * + * If this was the last value assigned to the specified key, the + * set assigned to that key will be removed as well. + * + * @param key The key of the binding. + * @param value The value to remove. + * @return A reference to this multimap. + */ def removeBinding(key: A, value: B): this.type = { get(key) match { case None => @@ -50,6 +80,12 @@ trait MultiMap[A, B] extends Map[A, Set[B]] { this } + /** Checks if there exists a binding to `key` such that it satisfies the predicate `p`. + * + * @param key The key for which the predicate is checked. + * @param p The predicate which a value assigned to the key must satisfy. + * @return A boolean if such a binding exists + */ def entryExists(key: A, p: B => Boolean): Boolean = get(key) match { case None => false case Some(set) => set exists p diff --git a/src/library/scala/collection/mutable/MutableList.scala b/src/library/scala/collection/mutable/MutableList.scala index 7784927c87..4324fa7ef9 100644 --- a/src/library/scala/collection/mutable/MutableList.scala +++ b/src/library/scala/collection/mutable/MutableList.scala @@ -15,12 +15,12 @@ package mutable import generic._ import immutable.{List, Nil} +// !!! todo: convert to LinkedListBuffer? /** <p> * This class is used internally to represent mutable lists. It is the * basis for the implementation of the classes * <code>Stack</code>, and <code>Queue</code>. * </p> - * !!! todo: convert to LinkedListBuffer? * * @author Matthias Zenger * @author Martin Odersky diff --git a/src/library/scala/collection/mutable/OpenHashMap.scala b/src/library/scala/collection/mutable/OpenHashMap.scala index 79bb96a0bf..cbcc19c3e8 100644 --- a/src/library/scala/collection/mutable/OpenHashMap.scala +++ b/src/library/scala/collection/mutable/OpenHashMap.scala @@ -57,6 +57,9 @@ class OpenHashMap[Key, Value](initialSize : Int) extends Map[Key, Value] import OpenHashMap.OpenEntry type Entry = OpenEntry[Key, Value] + /** + * A default constructor creates a hashmap with initial size 8. + */ def this() = this(8); override def empty: OpenHashMap[Key, Value] = OpenHashMap.empty[Key, Value] @@ -212,7 +215,7 @@ class OpenHashMap[Key, Value](initialSize : Int) extends Map[Key, Value] * * @param f The function to apply to each key, value mapping. */ - override def foreach[U](f : ((Key, Value)) => U){ + override def foreach[U](f : ((Key, Value)) => U) { val startModCount = modCount; foreachUndeletedEntry(entry => { if (modCount != startModCount) error("Concurrent Modification") diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 4d74a2ee74..eade376abe 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -144,10 +144,10 @@ class PriorityQueue[A](implicit ord: Ordering[A]) this } - /** Adds all elements provided by an <code>Iterable</code> object + /** Adds all elements provided by a `TraversableOnce` object * into the priority queue. * - * @param iter an iterable object + * @param xs an iterable object */ def ++(xs: TraversableOnce[A]) = { this.clone() ++= xs } @@ -206,14 +206,16 @@ class PriorityQueue[A](implicit ord: Ordering[A]) /** * Returns the reverse of this queue. The priority queue that gets * returned will have an inversed ordering - if for some elements - * <code>x</code> and <code>y</code> the original queue's ordering - * had <code>compare</code> returning an integer w, the new one will return -w, + * `x` and `y` the original queue's ordering + * had `compare` returning an integer ''w'', the new one will return ''-w'', * assuming the original ordering abides its contract. * * Note that the order of the elements will be reversed unless the - * <code>compare</code> method returns 0. In this case, such elements + * `compare` method returns 0. In this case, such elements * will be subsequent, but their corresponding subinterval may be inappropriately * reversed. However, due to the compare-equals contract, they will also be equal. + * + * @return A reversed priority queue. */ override def reverse = { val revq = new PriorityQueue[A]()(new math.Ordering[A] { diff --git a/src/library/scala/collection/mutable/PriorityQueueProxy.scala b/src/library/scala/collection/mutable/PriorityQueueProxy.scala index 427ffe478a..3f1ee5d217 100644 --- a/src/library/scala/collection/mutable/PriorityQueueProxy.scala +++ b/src/library/scala/collection/mutable/PriorityQueueProxy.scala @@ -11,7 +11,7 @@ package scala.collection package mutable -/** This class implements priority queues using a heap. The +/** This class servers as a proxy for priority queues. The * elements of the queue have to be ordered in terms of the * <code>Ordered[T]</code> class. * diff --git a/src/library/scala/collection/mutable/Seq.scala b/src/library/scala/collection/mutable/Seq.scala index a57d397275..8d11e14063 100644 --- a/src/library/scala/collection/mutable/Seq.scala +++ b/src/library/scala/collection/mutable/Seq.scala @@ -16,9 +16,10 @@ import generic._ /** A subtrait of <code>collection.Seq</code> which represents sequences * that can be mutated. - * The class adds an <code>update</code> method to <code>collection.Seq</code>. * - * @since 2.8 + * $seqInfo + * + * The class adds an <code>update</code> method to <code>collection.Seq</code>. */ trait Seq[A] extends Iterable[A] with scala.collection.Seq[A] diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala index 7004e52b8e..9dbfaf6d5e 100644 --- a/src/library/scala/collection/mutable/SetLike.scala +++ b/src/library/scala/collection/mutable/SetLike.scala @@ -26,7 +26,8 @@ import scala.annotation.migration * @version 2.8 * @since 2.8 * - * @define setnote @note + * @define setnote + * @note * This trait provides most of the operations of a `mutable.Set` independently of its representation. * It is typically inherited by concrete implementations of sets. * @@ -108,6 +109,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]] // abstract methods from Growable/Shrinkable + /** Adds a single element to the set. */ def +=(elem: A): this.type def -=(elem: A): this.type diff --git a/src/library/scala/collection/mutable/Stack.scala b/src/library/scala/collection/mutable/Stack.scala index 45e9fa24b2..c224c030a4 100644 --- a/src/library/scala/collection/mutable/Stack.scala +++ b/src/library/scala/collection/mutable/Stack.scala @@ -57,11 +57,11 @@ class Stack[A] private (var elems: List[A]) extends scala.collection.Seq[A] with */ def push(elem1: A, elem2: A, elems: A*): this.type = this.push(elem1).push(elem2).pushAll(elems) - /** Push all elements provided by the given iterator object onto - * the stack. The last element returned by the iterator + /** Push all elements in the given traversable object onto + * the stack. The last element in the traversable object * will be on top of the new stack. * - * @param elems the iterator object. + * @param xs the traversable object. * @return the stack with the new elements on top. */ def pushAll(xs: TraversableOnce[A]): this.type = { xs foreach push ; this } diff --git a/src/library/scala/collection/mutable/SynchronizedBuffer.scala b/src/library/scala/collection/mutable/SynchronizedBuffer.scala index 1c9a77c46a..0fef1a6635 100644 --- a/src/library/scala/collection/mutable/SynchronizedBuffer.scala +++ b/src/library/scala/collection/mutable/SynchronizedBuffer.scala @@ -54,18 +54,18 @@ trait SynchronizedBuffer[A] extends Buffer[A] { super.+=(elem) } - /** Appends a number of elements provided by an iterable object - * via its <code>iterator</code> method. The identity of the - * buffer is returned. + /** Appends a number of elements provided by a traversable object via + * its `foreach` method. + * The identity of the buffer is returned. * - * @param iter the iterable object. + * @param xs the traversable object. */ override def ++(xs: TraversableOnce[A]): Self = synchronized { super.++(xs) } - /** Appends a number of elements provided by an iterable object - * via its <code>iterator</code> method. + /** Appends a number of elements provided by a traversable object + * via its `foreach` method. * * @param iter the iterable object. */ @@ -81,10 +81,10 @@ trait SynchronizedBuffer[A] extends Buffer[A] { super.++=(elems) } - /** Appends a number of elements provided by an iterable object - * via its <code>iterator</code> method. + /** Appends a number of elements provided by a traversable object + * via its <code>foreach</code> method. * - * @param iter the iterable object. + * @param xs the traversable object. */ override def appendAll(xs: TraversableOnce[A]): Unit = synchronized { super.appendAll(xs) @@ -99,11 +99,11 @@ trait SynchronizedBuffer[A] extends Buffer[A] { super.+=:(elem) } - /** Prepends a number of elements provided by an iterable object - * via its <code>iterator</code> method. The identity of the + /** Prepends a number of elements provided by a traversable object + * via its <code>foreach</code> method. The identity of the * buffer is returned. * - * @param iter the iterable object. + * @param xs the traversable object. */ override def ++=:(xs: TraversableOnce[A]): this.type = synchronized[this.type] { super.++=:(xs) } @@ -113,11 +113,11 @@ trait SynchronizedBuffer[A] extends Buffer[A] { */ override def prepend(elems: A*): Unit = prependAll(elems) - /** Prepends a number of elements provided by an iterable object - * via its <code>iterator</code> method. The identity of the + /** Prepends a number of elements provided by a traversable object + * via its <code>foreach</code> method. The identity of the * buffer is returned. * - * @param iter the iterable object. + * @param xs the traversable object. */ override def prependAll(xs: TraversableOnce[A]): Unit = synchronized { super.prependAll(xs) @@ -139,10 +139,10 @@ trait SynchronizedBuffer[A] extends Buffer[A] { * one. Instead, it will insert a new element at index <code>n</code>. * * @param n the index where a new element will be inserted. - * @param iter the iterable object providing all elements to insert. + * @param xs the traversable object providing all elements to insert. */ - abstract override def insertAll(n: Int, iter: Traversable[A]): Unit = synchronized { - super.insertAll(n, iter) + abstract override def insertAll(n: Int, xs: Traversable[A]): Unit = synchronized { + super.insertAll(n, xs) } /** Replace element at index <code>n</code> with the new element diff --git a/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala b/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala index 9d18846252..933b3b41a4 100644 --- a/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala +++ b/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala @@ -12,7 +12,7 @@ package scala.collection package mutable -/** This class implements synchronized priority queues using a heap. +/** This class implements synchronized priority queues using a binary heap. * The elements of the queue have to be ordered in terms of the * <code>Ordered[T]</code> class. * @@ -39,13 +39,13 @@ class SynchronizedPriorityQueue[A](implicit ord: Ordering[A]) extends PriorityQu this } - /** Adds all elements provided by an iterator into the priority queue. + /** Adds all elements of a traversable object into the priority queue. * - * @param it an iterator + * @param xs a traversable object */ - override def ++=(it: TraversableOnce[A]): this.type = { + override def ++=(xs: TraversableOnce[A]): this.type = { synchronized { - super.++=(it) + super.++=(xs) } this } diff --git a/src/library/scala/collection/mutable/SynchronizedQueue.scala b/src/library/scala/collection/mutable/SynchronizedQueue.scala index e7630cee06..b09687a78e 100644 --- a/src/library/scala/collection/mutable/SynchronizedQueue.scala +++ b/src/library/scala/collection/mutable/SynchronizedQueue.scala @@ -36,11 +36,11 @@ class SynchronizedQueue[A] extends Queue[A] { */ override def +=(elem: A): this.type = synchronized[this.type] { super.+=(elem) } - /** Adds all elements provided by an <code>Iterable</code> object + /** Adds all elements provided by a `TraversableOnce` object * at the end of the queue. The elements are prepended in the order they * are given out by the iterator. * - * @param iter an iterable object + * @param xs a traversable object */ override def ++=(xs: TraversableOnce[A]): this.type = synchronized[this.type] { super.++=(xs) } diff --git a/src/library/scala/collection/mutable/SynchronizedStack.scala b/src/library/scala/collection/mutable/SynchronizedStack.scala index 4394d307eb..4940884302 100644 --- a/src/library/scala/collection/mutable/SynchronizedStack.scala +++ b/src/library/scala/collection/mutable/SynchronizedStack.scala @@ -39,16 +39,18 @@ class SynchronizedStack[A] extends Stack[A] { /** Push two or more elements onto the stack. The last element * of the sequence will be on top of the new stack. * - * @param elems the element sequence. - * @return the stack with the new elements on top. + * @param elem1 the first element to push. + * @param elem2 the second element to push. + * @param elems the element sequence that will be pushed. + * @return the stack with the new elements on top. */ override def push(elem1: A, elem2: A, elems: A*): this.type = synchronized[this.type] { super.push(elem1, elem2, elems: _*) } - /** Pushes all elements provided by an iterator - * on top of the stack. The elements are pushed in the order they - * are given out by the iterator. + /** Pushes all elements provided by a traversable object + * on top of the stack. The elements are pushed in the order the + * traversable object is traversed. * - * @param elems an iterator + * @param xs a traversable object */ override def pushAll(xs: TraversableOnce[A]): this.type = synchronized[this.type] { super.pushAll(elems) } diff --git a/src/library/scala/collection/mutable/Traversable.scala b/src/library/scala/collection/mutable/Traversable.scala index bdbcb9d97e..89c8868314 100644 --- a/src/library/scala/collection/mutable/Traversable.scala +++ b/src/library/scala/collection/mutable/Traversable.scala @@ -14,12 +14,9 @@ package mutable import generic._ -/** A subtrait of <code>collection.Traversable</code> which represents - * traversables that can be mutated. - * - * @author Martin Odersky - * @version 2.8 - * @since 2.8 +/** A trait for traversable collections that can be mutated. + * $traversableInfo + * @define mutability mutable */ trait Traversable[A] extends scala.collection.Traversable[A] with GenericTraversableTemplate[A, Traversable] diff --git a/src/library/scala/collection/mutable/WeakHashMap.scala b/src/library/scala/collection/mutable/WeakHashMap.scala index cad4dc2e43..8f496add1e 100644 --- a/src/library/scala/collection/mutable/WeakHashMap.scala +++ b/src/library/scala/collection/mutable/WeakHashMap.scala @@ -16,8 +16,9 @@ import JavaConversions._ import generic._ -/** - * @since 2.8 +/** A hash map with weak references to entries which are weakly reachable. + * + * @since 2.8 */ class WeakHashMap[A, B] extends JMapWrapper[A, B](new java.util.WeakHashMap) with JMapWrapperLike[A, B, WeakHashMap[A, B]] { diff --git a/src/library/scala/runtime/AbstractFunction0.scala b/src/library/scala/runtime/AbstractFunction0.scala index 1022a056f9..2d7d613132 100644 --- a/src/library/scala/runtime/AbstractFunction0.scala +++ b/src/library/scala/runtime/AbstractFunction0.scala @@ -8,9 +8,12 @@ package scala.runtime -abstract class AbstractFunction0[+R] extends Function0[R] { } -abstract class AbstractFunction1[-T1, +R] extends Function1[T1, R] { } -abstract class AbstractFunction2[-T1, -T2, +R] extends Function2[T1, T2, R] { } +abstract class AbstractFunction0[@specialized(Unit, Int, Long, Double) +R] extends Function0[R] { } +abstract class AbstractFunction1[@specialized(Int, Long, Double) -T1, + @specialized(Unit, Int, Long, Double) +R] extends Function1[T1, R] { } +abstract class AbstractFunction2[@specialized(Int, Long, Double) -T1, + @specialized(Int, Long, Double) -T2, + @specialized(Unit, Int, Long, Double) +R] extends Function2[T1, T2, R] { } abstract class AbstractFunction3[-T1, -T2, -T3, +R] extends Function3[T1, T2, T3, R] { } abstract class AbstractFunction4[-T1, -T2, -T3, -T4, +R] extends Function4[T1, T2, T3, T4, R] { } abstract class AbstractFunction5[-T1, -T2, -T3, -T4, -T5, +R] extends Function5[T1, T2, T3, T4, T5, R] { } 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/src/library/scala/specialized.scala b/src/library/scala/specialized.scala index 5ad2b0501f..4ac3037328 100644 --- a/src/library/scala/specialized.scala +++ b/src/library/scala/specialized.scala @@ -18,20 +18,17 @@ package scala * </code> * * Type T can be specialized on a subset of the primitive types by - * specifying a comma-separated string argument: + * specifying a list of primitive types to specialize at: * * <code> - * class MyList[@specialized("Int, Double, Boolean") T] .. + * class MyList[@specialized(Int, Double, Boolean) T] .. * </code> - * Only primitive types are supported and no name resolution is currently - * done on the string arguments (meaning imports and type aliases are - * not resolved). * * @since 2.8 */ -class specialized(types: String) extends StaticAnnotation { +class specialized(types: runtime.AnyValCompanion*) extends StaticAnnotation { def this() { - this("Boolean, Byte, Short, Char, Int, Long, Float, Double") + this(Unit, Boolean, Byte, Short, Char, Int, Long, Float, Double) } } diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index b781e46be5..3a08fa0482 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -54,6 +54,7 @@ private[scala] trait PropertiesTrait def clearProp(name: String) = System.clearProperty(name) def envOrElse(name: String, alt: String) = Option(System getenv name) getOrElse alt + def envOrNone(name: String) = Option(System getenv name) // for values based on propFilename def scalaPropOrElse(name: String, alt: String): String = scalaProps.getProperty(name, alt) diff --git a/src/partest/scala/tools/partest/Actions.scala b/src/partest/scala/tools/partest/Actions.scala index 3e745714cb..48b80cface 100644 --- a/src/partest/scala/tools/partest/Actions.scala +++ b/src/partest/scala/tools/partest/Actions.scala @@ -136,7 +136,7 @@ trait Actions { /** The default cleanup normalizes paths relative to sourcesDir. */ - def diffCleanup(f: File) = safeLines(f) map normalizePaths mkString "\n" + def diffCleanup(f: File) = safeLines(f) map normalizePaths mkString ("", "\n", "\n") /** If optional is true, a missing check file is considered * a successful diff. Necessary since many categories use @@ -146,19 +146,23 @@ trait Actions { def arg1 = tracePath(check) def arg2 = tracePath(log) def noCheck = !check.exists && returning(true)(_ => trace("diff %s %s [unchecked]".format(arg1, arg2))) + def output = diffCleanup(log) + def matches = safeSlurp(check).trim == output.trim + + def traceMsg = + if (isDryRun) "diff %s %s".format(arg1, arg2) + else "diff %s %s [%s]".format(arg1, arg2, (if (matches) "passed" else "failed")) noCheck || { - def result = safeSlurp(check).trim == diffCleanup(log).trim - def msg = if (result) "passed" else "failed" + trace(traceMsg) - if (isDryRun) { - trace("diff %s %s".format(arg1, arg2)) + isDryRun || matches || (isUpdateCheck && { + normal("** diff %s %s failed:\n".format(arg1, arg2)) + normal(diffOutput()) + normal("** updating %s and marking as passed.\n".format(arg1)) + check writeAll output true - } - else { - trace("diff %s %s [%s]".format(arg1, arg2, msg)) - result - } + }) } } diff --git a/src/partest/scala/tools/partest/Compilable.scala b/src/partest/scala/tools/partest/Compilable.scala index a1d987ad6d..c11532f278 100644 --- a/src/partest/scala/tools/partest/Compilable.scala +++ b/src/partest/scala/tools/partest/Compilable.scala @@ -27,8 +27,10 @@ trait PartestCompilation { // } def javac(args: List[String]): Boolean = { + val allArgString = fromArgs(javacpArg :: javacOpts :: args) + // javac -d outdir -classpath <basepath> <files> - val cmd = "%s -d %s %s %s".format(javacCmd, outDir, javacpArg, fromArgs(args)) + val cmd = "%s -d %s %s".format(javacCmd, outDir, allArgString) def traceMsg = if (isVerbose) cmd else "%s -d %s %s".format(tracePath(Path(javacCmd)), tracePath(outDir), fromArgs(args)) diff --git a/src/partest/scala/tools/partest/Config.scala b/src/partest/scala/tools/partest/Config.scala index 7d8bb80835..288a3034e9 100644 --- a/src/partest/scala/tools/partest/Config.scala +++ b/src/partest/scala/tools/partest/Config.scala @@ -23,8 +23,6 @@ trait Config { * run we only allocate one worker so the output isn't interspersed. */ def workerTimeout = 3600 // 1 hour, probably overly generous - def testTimeout = testTimeout_ flatMap safeToInt getOrElse 900 // test timeout - def testWarning = testWarning_ flatMap safeToInt getOrElse (testTimeout / 10) // test warning def numWorkers = if (isDryRun) 1 else propOrElse("partest.actors", "8").toInt def expectedErrors = propOrElse("partest.errors", "0").toInt def poolSize = (wrapAccessControl(propOrNone("actors.corePoolSize")) getOrElse "16").toInt @@ -121,6 +119,7 @@ trait Config { "Java binaries in: " + javaBin, "Java runtime is: " + javaInfoString, "Java runtime options: " + (Process.javaVmArguments mkString " "), + "Javac options are: " + universe.javacOpts, "Java options are: " + universe.javaOpts, "Source directory is: " + src, "Selected categories: " + (selectedCategories mkString " "), diff --git a/src/partest/scala/tools/partest/Partest.scala b/src/partest/scala/tools/partest/Partest.scala index 019ed270e5..d6adcc6053 100644 --- a/src/partest/scala/tools/partest/Partest.scala +++ b/src/partest/scala/tools/partest/Partest.scala @@ -6,7 +6,7 @@ package scala.tools package partest import nsc.io._ -import nsc.util.CommandLine +import nsc.util._ import category.AllCategories /** Global object for a Partest run. It is completely configured by the list @@ -15,10 +15,15 @@ import category.AllCategories * for the complete list. */ class Partest(args: List[String]) extends { - val parsed = PartestSpecReference(args: _*) -} with Universe with PartestSpec with AllCategories { + val parsed = PartestSpec(args: _*) +} with Universe with PartestSpec with cmd.Instance with AllCategories { - debug("Partest object created with args: " + (args mkString " ")) + if (parsed.propertyArgs.nonEmpty) + debug("Partest property args: " + fromArgs(parsed.propertyArgs)) + + debug("Partest created with args: " + fromArgs(args)) + + def helpMsg = PartestSpec.helpMsg // The abstract values from Universe. lazy val testBuildDir = searchForDir(buildDir) @@ -30,7 +35,6 @@ class Partest(args: List[String]) extends { // Coarse validation of partest directory: holds a file called partest. (partestDir / "partest").isFile || error("'%s' is not a valid partest directory." format partestDir) - def runSets = toArgs(parsed.getOrElse("--runsets", "")) def specifiedTests = parsed.residualArgs map (x => Path(x).normalize) def specifiedKinds = testKinds filter (x => isSet(x) || (runSets contains x)) def specifiedCats = specifiedKinds flatMap (x => allCategories find (_.kind == x)) diff --git a/src/partest/scala/tools/partest/PartestSpec.scala b/src/partest/scala/tools/partest/PartestSpec.scala index a8a1d9b0cb..50c82fb783 100644 --- a/src/partest/scala/tools/partest/PartestSpec.scala +++ b/src/partest/scala/tools/partest/PartestSpec.scala @@ -6,9 +6,8 @@ package scala.tools package partest -import Properties._ import nsc.io._ -import nsc.util.{ CommandLine, CommandLineSpec, CommandLineReferenceSpec } +import cmd._ /** This takes advantage of bits of scala goodness to fully define a command * line program with a minimum of duplicated code. When the specification object @@ -16,93 +15,91 @@ import nsc.util.{ CommandLine, CommandLineSpec, CommandLineReferenceSpec } * a private accumulator. What emerges is a full list of the valid unary * and binary arguments, as well as autogenerated help. */ -trait PartestSpec extends CommandLineSpec { - override def isPassthroughProperty(key: String) = key == "partest.options" - override def isSysPropOption(key: String) = { - val segments = (key split '.').toList - if (segments.size == 2 && segments.head == "partest") Some(segments.last) - else None - } - - private var _testKinds: List[String] = Nil - private def kind(s: String) = returning(s)(_testKinds +:= _) +trait PartestSpec extends Spec with Meta.StdOpts with Interpolation { + def referenceSpec = PartestSpec + def programInfo = Spec.Names("partest", "scala.tools.partest.Runner") + private val kind = new Spec.Accumulator[String]() + protected def testKinds = kind.get - def testKinds = _testKinds - def versionMsg = Properties.versionMsg + private implicit val tokenizeString = FromString.ArgumentsFromString // String => List[String] help(""" + |# Pro Tip! Instant bash completion: `partest --bash` (note backticks) |Usage: partest [<options>] [<test> <test> ...] | <test>: a path to a test designator, typically a .scala file or a directory. - | Examples: files/pos/test1.scala, files/res/bug785""") - - heading ("Test categories:") - val isAll = ("all" / "run all tests (default, unless no options given)" ?) - (kind("pos") / "Compile files that are expected to build" ?) - (kind("neg") / "Compile files that are expected to fail" ?) - (kind("run") / "Test JVM backend" ?) - (kind("jvm") / "Test JVM backend" ?) - (kind("res") / "Run resident compiler scenarii" ?) - (kind("buildmanager") / "Run Build Manager scenarii" ?) - (kind("scalacheck") / "Run Scalacheck tests" ?) - (kind("script") / "Run script files" ?) - (kind("shootout") / "Run shootout tests" ?) - (kind("scalap") / "Run scalap tests" ?) + | Examples: files/pos/test1.scala, files/res/bug785 + | + | Test categories:""".stripMargin) + + val isAll = ("all" / "run all tests (default, unless no options given)" --?) + (kind("pos") / "Compile files that are expected to build" --?) + (kind("neg") / "Compile files that are expected to fail" --?) + (kind("run") / "Test JVM backend" --?) + (kind("jvm") / "Test JVM backend" --?) + (kind("res") / "Run resident compiler scenarii" --?) + (kind("buildmanager") / "Run Build Manager scenarii" --?) + (kind("scalacheck") / "Run Scalacheck tests" --?) + (kind("script") / "Run script files" --?) + (kind("shootout") / "Run shootout tests" --?) + (kind("scalap") / "Run scalap tests" --?) heading ("""Test "smart" categories:""") - val grepExpr = "grep" / "run all tests with a source file containing <expr>" >> - val isFailed = "failed" / "run all tests which failed on the last run" ? + val grepExpr = "grep" / "run all tests with a source file containing <expr>" --| + val isFailed = "failed" / "run all tests which failed on the last run" --? heading ("Specifying paths and additional flags, ~ means repository root:") - val rootDir = "rootdir" / "path from ~ to partest (default: test)" |> "test" - val buildDir = "builddir" / "path from ~ to test build (default: build/pack)" |> "build/pack" - val srcDir = "srcdir" / "path from --rootdir to sources (default: files)" |> "files" - val javaOpts = "javaopts" / "flags to java on all runs (overrides JAVA_OPTS)" |> envOrElse("JAVA_OPTS", "") - val scalacOpts = "scalacopts" / "flags to scalac on all tests (overrides SCALAC_OPTS)" |> envOrElse("SCALAC_OPTS", "") - ("pack" / "alias for --builddir build/pack") ?+> List("--builddir", "build/pack") - ("quick" / "alias for --builddir build/quick") ?+> List("--builddir", "build/quick") + val rootDir = "rootdir" / "path from ~ to partest" defaultTo "test" + val buildDir = "builddir" / "path from ~ to test build" defaultTo "build/pack" + val srcDir = "srcdir" / "path from --rootdir to sources" defaultTo "files" + val javaOpts = "javaopts" / "flags to java on all runs" defaultToEnv "JAVA_OPTS" + val javacOpts = "javacopts" / "flags to javac on all runs" defaultToEnv "JAVAC_OPTS" + val scalacOpts = "scalacopts" / "flags to scalac on all tests" defaultToEnv "SCALAC_OPTS" + + "pack" / "" expandTo ("--builddir", "build/pack") + "quick" / "" expandTo ("--builddir", "build/quick") heading ("Options influencing output:") - val isTrace = "trace" / "show the individual steps taken by each test" ? - val isShowDiff = "show-diff" / "show diff between log and check file" ? - val isShowLog = "show-log" / "show log on failures" ? - val isDryRun = "dry-run" / "do not run tests, only show their traces." ? - val isTerse = "terse" / "be less verbose (almost silent except for failures)" ? - val isVerbose = "verbose" / "be more verbose (additive with --trace)" ? - val isDebug = "debug" / "maximum debugging output" ? - val isAnsi = "ansi" / "print output in color" ? + val isTrace = "trace" / "show the individual steps taken by each test" --? + val isShowDiff = "show-diff" / "show diff between log and check file" --? + val isShowLog = "show-log" / "show log on failures" --? + val isDryRun = "dry-run" / "do not run tests, only show their traces." --? + val isTerse = "terse" / "be less verbose (almost silent except for failures)" --? + val isVerbose = "verbose" / "be more verbose (additive with --trace)" --? + val isDebug = "debug" / "maximum debugging output" --? + val isAnsi = "ansi" / "print output in color" --? heading ("Other options:") - val timeout_ = "timeout" / "Overall timeout in seconds" |> "14400" - val testWarning_ = "test-warning" / "Test warning in seconds" >> ; // defaults to testTimeout / 10 - val testTimeout_ = "test-timeout" / "Test timeout in seconds" >> ; // defaults to 900 - val isCleanup = "cleanup" / "delete all stale files and dirs before run" ? - val isNoCleanup = "nocleanup" / "do not delete any logfiles or object dirs" ? - val isStats = "stats" / "collect and print statistics about the tests" ? - val isValidate = "validate" / "examine test filesystem for inconsistencies" ? - val isVersion = "version" / "print version" ? + val timeout = "timeout" / "Overall timeout in seconds" defaultTo 14400 + val testWarning = "test-warning" / "Test warning in seconds" defaultTo 90 + val testTimeout = "test-timeout" / "Test timeout in seconds" defaultTo 900 + val isCleanup = "cleanup" / "delete all stale files and dirs before run" --? + val isNoCleanup = "nocleanup" / "do not delete any logfiles or object dirs" --? + val isStats = "stats" / "collect and print statistics about the tests" --? + val isValidate = "validate" / "examine test filesystem for inconsistencies" --? + val isUpdateCheck = "update-check" / "overwrite checkFile if diff fails" --? + + "version" / "print version" --> runAndExit(println(Properties.versionMsg)) // no help for anything below this line - secret options // mostly intended for property configuration. - val runsets = "runsets" |> "" - val isNoAlarms = ("noalarms" ?) - val isInsideAnt = ("is-in-ant" ?) + val runSets = ("runsets" --^) getOrElse Nil + val isNoAlarms = "noalarms" --? + val isInsideAnt = "is-in-ant" --? } -object PartestSpecReference extends PartestSpec with CommandLineReferenceSpec { - import CommandLineSpec._ +object PartestSpec extends PartestSpec with Property { + lazy val propMapper = new PropertyMapper(PartestSpec) { + override def isPassThrough(key: String) = key == "partest.options" + } - def parsed: CommandLine = null - override def creator(args: List[String]) = - new ThisCommandLine(args) { - override def onlyKnownOptions = true - override def errorFn(msg: String) = printAndExit("Error: " + msg) - } + type ThisCommandLine = PartestCommandLine + class PartestCommandLine(args: List[String]) extends SpecCommandLine(args) { + override def onlyKnownOptions = true + override def errorFn(msg: String) = printAndExit("Error: " + msg) - def main(args: Array[String]): Unit = println(bashCompletion("partest")) + def propertyArgs = PartestSpec.propertyArgs + } - /** Append bash completion for partest to the given file. - */ - def appendCompletionTo(f: File) = f appendAll bashCompletion("partest") + override def creator(args: List[String]): PartestCommandLine = new PartestCommandLine(args) } - diff --git a/src/partest/scala/tools/partest/Runner.scala b/src/partest/scala/tools/partest/Runner.scala index 7f67c93478..1a28e60896 100644 --- a/src/partest/scala/tools/partest/Runner.scala +++ b/src/partest/scala/tools/partest/Runner.scala @@ -9,13 +9,10 @@ package partest import nsc.io._ object Runner { - def main(mainArgs: Array[String]) { - val propArgs = PartestSpecReference.sysPropsAsOptions() - val args = (propArgs ++ mainArgs).toList + def main(args: Array[String]) { val runner = Partest(args: _*) import runner._ - if (isVersion) return println(versionMsg) if (args.isEmpty) return println(helpMsg) if (isValidate) return validateAll() diff --git a/src/partest/scala/tools/partest/ant/JavaTask.scala b/src/partest/scala/tools/partest/ant/JavaTask.scala index 0bebf91368..6740554dd8 100644 --- a/src/partest/scala/tools/partest/ant/JavaTask.scala +++ b/src/partest/scala/tools/partest/ant/JavaTask.scala @@ -12,19 +12,21 @@ package ant import org.apache.tools.ant.Task import org.apache.tools.ant.taskdefs.Java -import org.apache.tools.ant.types.{ EnumeratedAttribute, Commandline, Environment, PropertySet } +import org.apache.tools.ant.types.Environment import scala.tools.nsc.io._ -import scala.tools.nsc.util.{ ClassPath, CommandLineSpec } -import CommandLineSpec._ +import scala.tools.nsc.util.ClassPath +import cmd.Spec._ class JavaTask extends Java { override def getTaskName() = "partest" private val scalaRunnerClass = "scala.tools.nsc.MainGenericRunner" + private val partestRunnerClass = "scala.tools.partest.Runner" + def defaultJvmArgs = "-Xms64M -Xmx768M -Xss768K -XX:MaxPermSize=96M" protected def rootDir = prop("partest.rootdir") getOrElse (baseDir / "test").path - protected def partestJVMArgs = prop("partest.jvm.args") getOrElse "-Xms64M -Xmx768M -Xss768K -XX:MaxPermSize=96M" - protected def runnerArgs = List("-usejavacp", "scala.tools.partest.Runner", "--javaopts", partestJVMArgs) + protected def partestJVMArgs = prop("partest.jvm.args") getOrElse defaultJvmArgs + protected def runnerArgs = List("-usejavacp", partestRunnerClass, "--javaopts", partestJVMArgs) private def baseDir = Directory(getProject.getBaseDir) private def prop(s: String) = Option(getProject getProperty s) diff --git a/src/partest/scala/tools/partest/ant/PartestTask.scala b/src/partest/scala/tools/partest/ant/PartestTask.scala deleted file mode 100644 index 65848fabb0..0000000000 --- a/src/partest/scala/tools/partest/ant/PartestTask.scala +++ /dev/null @@ -1,90 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala Parallel Testing ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -/**** Note -- this isn't used anymore, but I left it in for the moment. ****/ - -package scala.tools -package partest -package ant - -import java.io.{ File => JFile } - -import org.apache.tools.ant.Task -import org.apache.tools.ant.types.{ Reference, FileSet} - -import scala.reflect.BeanProperty -import scala.tools.ant.sabbus.CompilationPathProperty -import scala.tools.nsc.io -import scala.tools.nsc.util.CommandLineSpec._ - -class PartestTask extends Task with CompilationPathProperty { - /** Used only in ant task */ - @BeanProperty protected var errorOnFailed: Boolean = _ - @BeanProperty protected var jUnitReportDir: JFile = _ - - /** Propagated to partest run via system properties */ - @BeanProperty protected var debug: Boolean = _ - @BeanProperty protected var javaOpts: String = _ - @BeanProperty protected var partestOpts: String = _ - @BeanProperty protected var runSets: String = _ - @BeanProperty protected var scalacOpts: String = _ - @BeanProperty protected var showDiff: Boolean = _ - @BeanProperty protected var showLog: Boolean = _ - @BeanProperty protected var srcDir: String = _ - @BeanProperty protected var timeout: Int = _ - - /** Translating ant information into command line arguments. */ - private def notEmpty(s: String) = s != null && s.length > 0 - private def quoted(s: String) = if (s exists (_.isWhitespace)) "\"" + s.trim + "\"" else s - private def optionCollection = List[(Boolean, () => List[String])]( - debug -> (() => List("--debug")), - showLog -> (() => List("--show-log")), - showDiff -> (() => List("--show-diff")), - (timeout > 0) -> (() => List("--timeout", timeout.toString)), - notEmpty(javaOpts) -> (() => List("--javaopts", javaOpts)), - notEmpty(scalacOpts) -> (() => List("--scalacopts", scalacOpts)), - notEmpty(srcDir) -> (() => List("--srcdir", srcDir)), - notEmpty(partestOpts) -> (() => toArgs(partestOpts)) - ) - - private def antPropOrNone(name: String) = Option(getProject getProperty name) - private def antPropsToCommandLine() = { - setProp("partest.isInAnt", "true") - val partestDir = antPropOrNone("partest.dir") getOrElse error("Mandatory attribute 'partest.dir' is not set.") - - val root = List("--rootdir", io.Path(partestDir).path) - val opts = optionCollection collect { case (true, f) => f() } flatten - val sets = Option(runSets).toList flatMap toArgs map toOpt - - root ++ opts ++ sets - } - private def antRunTests() = { - val args = antPropsToCommandLine() - val runner = Partest(args: _*) - import runner._ - - normal("Ant options translate to command line: partest " + fromArgs(args)) - printConfigBanner() - - val result = launchTestSuite() - val msg = result.toString - - if (result.hasFailures && errorOnFailed) error(msg) - else log(msg) - } - - override def execute() { - try antRunTests() - catch { - case x => - System.err.println("Uncaught exception %s in partest ant ask: aborting." format x) - x.printStackTrace() - throw x - } - } -} diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala index 3ef4db7cd8..f6d216e379 100644 --- a/src/partest/scala/tools/partest/package.scala +++ b/src/partest/scala/tools/partest/package.scala @@ -5,7 +5,6 @@ package scala.tools import nsc.io.{ File, Path, Process, Directory } -import nsc.util.CommandLineSpec import java.nio.charset.CharacterCodingException package object partest { @@ -18,13 +17,12 @@ package object partest { private[partest] def safeLines(f: File) = safeSlurp(f) split """\r\n|\r|\n""" toList private[partest] def safeArgs(f: File) = toArgs(safeSlurp(f)) - private[partest] def safeToInt(s: String) = try Some(s.toInt) catch { case _: NumberFormatException => None } private[partest] def isJava(f: Path) = f.isFile && (f hasExtension "java") private[partest] def isScala(f: Path) = f.isFile && (f hasExtension "scala") private[partest] def isJavaOrScala(f: Path) = isJava(f) || isScala(f) - private[partest] def toArgs(line: String) = CommandLineSpec toArgs line - private[partest] def fromArgs(args: List[String]) = CommandLineSpec fromArgs args + private[partest] def toArgs(line: String) = cmd toArgs line + private[partest] def fromArgs(args: List[String]) = cmd fromArgs args /** Strings, argument lists, etc. */ diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala index 26b01634f5..3cb70ec04e 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala @@ -290,7 +290,12 @@ class ScalaSigPrinter(stream: PrintStream, printPrivates: Boolean) { val value = attrib.value.get val stringVal = value.isInstanceOf[String] if (stringVal) buffer.append("\"") + val stringValue = valueToString(value) + val isMultiline = stringVal && (stringValue.contains("\n") + || stringValue.contains("\r")) + if (isMultiline) buffer.append("\"\"") buffer.append(valueToString(value)) + if (isMultiline) buffer.append("\"\"") if (stringVal) buffer.append("\"") buffer.append(")") } diff --git a/test/files/run/Course-2002-10-msil.check b/test/disabled/run/Course-2002-10-msil.check index bbd9414370..bbd9414370 100644 --- a/test/files/run/Course-2002-10-msil.check +++ b/test/disabled/run/Course-2002-10-msil.check diff --git a/test/files/run/Course-2002-10.check b/test/disabled/run/Course-2002-10.check index 207b671f05..207b671f05 100644 --- a/test/files/run/Course-2002-10.check +++ b/test/disabled/run/Course-2002-10.check diff --git a/test/files/run/Course-2002-10.scala b/test/disabled/run/Course-2002-10.scala index e978bc8258..e978bc8258 100644 --- a/test/files/run/Course-2002-10.scala +++ b/test/disabled/run/Course-2002-10.scala diff --git a/test/files/run/Course-2002-13.check b/test/disabled/run/Course-2002-13.check index 7664f70576..7664f70576 100644 --- a/test/files/run/Course-2002-13.check +++ b/test/disabled/run/Course-2002-13.check diff --git a/test/files/run/Course-2002-13.scala b/test/disabled/run/Course-2002-13.scala index c016d41a90..c016d41a90 100644 --- a/test/files/run/Course-2002-13.scala +++ b/test/disabled/run/Course-2002-13.scala diff --git a/test/files/run/streamWithFilter.check b/test/disabled/run/streamWithFilter.check index 6b0e91a147..6b0e91a147 100644 --- a/test/files/run/streamWithFilter.check +++ b/test/disabled/run/streamWithFilter.check diff --git a/test/files/run/streamWithFilter.scala b/test/disabled/run/streamWithFilter.scala index cb919d4f55..cb919d4f55 100644 --- a/test/files/run/streamWithFilter.scala +++ b/test/disabled/run/streamWithFilter.scala diff --git a/test/files/buildmanager/t2652/t2652.check b/test/files/buildmanager/t2652/t2652.check index 77a27a727f..0e685c1f94 100644 --- a/test/files/buildmanager/t2652/t2652.check +++ b/test/files/buildmanager/t2652/t2652.check @@ -3,7 +3,7 @@ compiling Set(A.scala, B.scala) Changes: Map() builder > A.scala compiling Set(A.scala) -Changes: Map(class A -> List(Changed(Definition(A.x))[method x changed from [T](t: T)T to [T](t: T)T flags: <method>])) +Changes: Map(class A -> List(Added(Definition(A.x$mBc$sp)), Added(Definition(A.x$mCc$sp)), Added(Definition(A.x$mDc$sp)), Added(Definition(A.x$mFc$sp)), Added(Definition(A.x$mIc$sp)), Added(Definition(A.x$mLc$sp)), Added(Definition(A.x$mSc$sp)), Added(Definition(A.x$mVc$sp)), Added(Definition(A.x$mZc$sp)), Changed(Definition(A.x))[method x changed from [T](t: T)T to [T](t: T)T flags: <method>])) invalidate B.scala because it references changed definition [Changed(Definition(A.x))[method x changed from [T](t: T)T to [T](t: T)T flags: <method>]] compiling Set(B.scala) Changes: Map(object B -> List()) 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 } - } -} diff --git a/test/files/pos/spec-Function1.flags b/test/files/pos/spec-Function1.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-Function1.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-List.flags b/test/files/pos/spec-List.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-List.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-annotations.flags b/test/files/pos/spec-annotations.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-annotations.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-arrays.flags b/test/files/pos/spec-arrays.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-arrays.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-cyclic.flags b/test/files/pos/spec-cyclic.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-cyclic.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-example1.flags b/test/files/pos/spec-example1.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-example1.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-fields.flags b/test/files/pos/spec-fields.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-fields.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-foo.flags b/test/files/pos/spec-foo.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-foo.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-funs.flags b/test/files/pos/spec-funs.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-funs.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-lists.flags b/test/files/pos/spec-lists.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-lists.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-localdefs.flags b/test/files/pos/spec-localdefs.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-localdefs.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-maps.flags b/test/files/pos/spec-maps.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-maps.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-params.flags b/test/files/pos/spec-params.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-params.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-partially.flags b/test/files/pos/spec-partially.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-partially.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-polymeth.flags b/test/files/pos/spec-polymeth.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-polymeth.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-sealed.flags b/test/files/pos/spec-sealed.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-sealed.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-short.flags b/test/files/pos/spec-short.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-short.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-simple.flags b/test/files/pos/spec-simple.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-simple.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-super.flags b/test/files/pos/spec-super.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-super.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-tailcall.flags b/test/files/pos/spec-tailcall.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-tailcall.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/pos/spec-thistype.flags b/test/files/pos/spec-thistype.flags deleted file mode 100644 index 973517e1c9..0000000000 --- a/test/files/pos/spec-thistype.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index 8557047875..3442ecafc3 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -304,6 +304,27 @@ object Test extends Application { } + // #3207 + trait P3207[T] { + class Inner(val f: T => Unit = (x: T) => println(x)) + } + + object Test3207_1 { + val p = new P3207[Int] {} + val q = new p.Inner() { + def g = 0 + } + } + + object Test3207_2 { + val p = new P3207[Int] { + val inner = new Inner() { + def g = 0 + } + } + } + + // DEFINITIONS def test1(a: Int, b: String) = println(a +": "+ b) def test2(u: Int, v: Int)(k: String, l: Int) = println(l +": "+ k +", "+ (u + v)) diff --git a/test/files/run/programmatic-main.check b/test/files/run/programmatic-main.check index 82118f8ece..3429195265 100644 --- a/test/files/run/programmatic-main.check +++ b/test/files/run/programmatic-main.check @@ -10,6 +10,7 @@ liftcode selectivecps uncurry tailcalls +specialize explicitouter erasure lazyvals diff --git a/test/files/run/spec-absfun.flags b/test/files/run/spec-absfun.flags deleted file mode 100644 index 3a910a936c..0000000000 --- a/test/files/run/spec-absfun.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize
\ No newline at end of file diff --git a/test/files/run/spec-absfun.scala b/test/files/run/spec-absfun.scala index ab16e8febc..2b780548f5 100644 --- a/test/files/run/spec-absfun.scala +++ b/test/files/run/spec-absfun.scala @@ -37,7 +37,7 @@ class Pair[A](_first: A, _second: A) { def second = _second } -class SpecializedPair[@specialized("Int") A](_first: A, _second: A) { +class SpecializedPair[@specialized(Int) A](_first: A, _second: A) { def first = _first def second = _second } diff --git a/test/files/run/spec-matrix.flags b/test/files/run/spec-matrix.flags deleted file mode 100644 index 3a910a936c..0000000000 --- a/test/files/run/spec-matrix.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize
\ No newline at end of file diff --git a/test/files/run/spec-matrix.scala b/test/files/run/spec-matrix.scala index 212a800672..81e3eaf212 100644 --- a/test/files/run/spec-matrix.scala +++ b/test/files/run/spec-matrix.scala @@ -43,7 +43,7 @@ object Test { } - def multManifest[@specialized("Int") T](m: Matrix[T], n: Matrix[T])(implicit cm: ClassManifest[T], num: Numeric[T]) { + def multManifest[@specialized(Int) T](m: Matrix[T], n: Matrix[T])(implicit cm: ClassManifest[T], num: Numeric[T]) { val p = new Matrix[T](m.rows, n.cols) import num._ diff --git a/test/files/run/spec-patmatch.flags b/test/files/run/spec-patmatch.flags deleted file mode 100644 index 3a910a936c..0000000000 --- a/test/files/run/spec-patmatch.flags +++ /dev/null @@ -1 +0,0 @@ --Yspecialize
\ No newline at end of file diff --git a/test/partest b/test/partest index 124c4d605e..87c7961689 100755 --- a/test/partest +++ b/test/partest @@ -75,11 +75,11 @@ if $cygwin; then fi # Reminder: substitution ${JAVA_OPTS:=-Xmx256M -Xms16M} DO NOT work on Solaris -[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:MaxPermSize=128M" +[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xms64M -Xmx1024M -Xss768K -XX:MaxPermSize=96M" [ -n "$SCALAC_OPTS" ] || SCALAC_OPTS="" -export SCALAC_OPTS -export JAVA_OPTS +# export SCALAC_OPTS +# export JAVA_OPTS export JAVACMD ${JAVACMD:=java} $JAVA_OPTS \ |