diff options
303 files changed, 2727 insertions, 7044 deletions
diff --git a/build.examples.xml b/build.examples.xml deleted file mode 100644 index 82432121ca..0000000000 --- a/build.examples.xml +++ /dev/null @@ -1,256 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<project name="scala-examples" default="build"> - - <description> - I am SABBUS for ${ant.project.name}, the build system for the Scala compiler - and core library. Please check the 'docs/README' file for more information - about me. - </description> - - <echo level="info" message="Running SABBUS for ${ant.project.name}..."/> - -<!-- =========================================================================== -PROPERTIES -============================================================================ --> - - <property environment="env"/> - - <!-- Prevents system classpath from being used --> - <property name="build.sysclasspath" value="ignore"/> - - <!-- Base properties --> - <property name="src.dir" value="${basedir}/docs"/> - <property name="src.examples.dir" value="${src.dir}/examples"/> - <property name="lib.dir" value="${basedir}/lib"/> - <!-- User properties --> - <property file="${basedir}/build.examples.properties"/> - <!-- Location of pre-compiled libraries properties --> - <property name="scala.lib.jar" value="${lib.dir}/scala-library.jar"/> - <property name="scala.comp.jar" value="${lib.dir}/scala-compiler.jar"/> - <property name="ant.jar" value="${ant.home}/lib/ant.jar"/> - <property name="ant-contrib.jar" value="${lib.dir}/ant/ant-contrib.jar"/> - <!-- --> - <property name="build.dir" value="${basedir}/build"/> - <property name="build.examples.dir" value="${build.dir}/examples"/> - <!-- tbd --> - <property name="excludes.compile" - value="**/*current.*,**/parsers2.*,**/typeinf.*"/> - <property name="excludes.run" - value="**/Parsers.*"/> - -<!-- =========================================================================== -INITIALISATION -============================================================================ --> - - <target name="init" unless="init.avail"> - <tstamp prefix="start"> - <format - property="human-time" - pattern="EEEE, d MMMM yyyy, HH:mm:ss (zz)" - /> - </tstamp> - <!-- Testing if everything is in place --> - <echo level="verbose" message="scala.lib.jar=${scala.lib.jar}"/> - <fail message="Scala library in '${lib.dir}/' is not available"> - <condition><not><and> - <available - classname="scala.Predef" - classpath="${scala.lib.jar}" - /> - <available - classname="scala.collection.immutable.List" - classpath="${scala.lib.jar}" - /> - <available - classname="scala.runtime.ObjectRef" - classpath="${scala.lib.jar}" - /> - </and></not></condition> - </fail> - <echo level="verbose" message="scala.comp.jar=${scala.comp.jar}"/> - <fail message="Scala compiler in '${lib.dir}/' is not available"> - <condition><not> - <available - classname="scala.tools.ant.Scalac" - classpath="${scala.comp.jar}:${scala.lib.jar}" - /> - </not></condition> - </fail> - <echo level="verbose" message="ant.jar=${ant.jar}"/> - <echo level="verbose" message="ant-contrib.jar=${ant-contrib.jar}"/> - <fail message="Additional Ant tasks in '${lib.dir}/' is not available"> - <condition><not> - <available - classname="net.sf.antcontrib.AntContribVersion" - classpath="${ant-contrib.jar}" - /> - </not></condition> - </fail> - <!-- Creating class-pathes --> - <path id="scala.classpath"> - <pathelement location="${scala.lib.jar}"/> - <pathelement location="${scala.comp.jar}"/> - </path> - <!-- Creating boot-level tasks --> - <taskdef resource="net/sf/antcontrib/antlib.xml"> - <classpath> - <pathelement location="${ant-contrib.jar}"/> - </classpath> - </taskdef> - <!-- Finding out what system architecture is being used --> - <condition property="os.win"> - <os family="windows"/> - </condition> - <if><isset property="os.win"/> - <then> - <exec - executable="cygpath" - vmlauncher="no" - errorproperty="cygpath.err" - outputproperty="cygpath.out" - > - <arg value="--windir"/> - </exec> - <condition property="os.cygwin"> - <equals arg1="${cygpath.err}" arg2=""/> - </condition> - </then> - </if> - <condition property="os.unix"> - <or> - <os family="unix"/> - <os family="mac"/> - <isset property="os.cygwin"/> - </or> - </condition> - <if><isset property="os.cygwin"/> - <then><property name="os.type" value="Cygwin"/></then> - <elseif><isset property="os.win"/> - <then><property name="os.type" value="Windows"/></then> - </elseif> - <elseif><isset property="os.unix"/> - <then><property name="os.type" value="UNIX"/></then> - </elseif> - <else> - <fail>System environment could not be determined</fail> - </else> - </if> - <echo - level="info" - message="OS: ${os.type} (${os.name} ${os.arch} ${os.version});" - /> - <echo - level="info" - message="Java: ${java.version} ('${java.home}');" - /> - <echo - level="info" - message="JVM: ${java.vm.name} ${java.vm.version};" - /> - <echo - level="info" - message="Ant: ${ant.version}." - /> - <property name="init.avail" value="yes"/> - </target> - - <target name="setup" depends="init"> - <!-- Creating boot-level tasks --> - <taskdef - name="scalac" - classname="scala.tools.ant.Scalac" - classpathref="scala.classpath" - /> - <property name="init.avail" value="yes"/> - </target> - -<!-- =========================================================================== -BUILD -============================================================================ --> - - <target name="build" depends="setup"> - <mkdir dir="${build.dir}"/> - <echo level="verbose">src.dir=${src.dir}</echo> - <pathconvert property="list" pathsep=","> - <path> - <fileset - dir="${src.dir}" - includes="examples/*.scala" - excludes="${excludes.compile}" - /> - </path> - <mapper> - <globmapper from="${src.dir}/*" to="*"/> - </mapper> - </pathconvert> - <for list="${list}" param="file"> - <sequential> - <scalac srcdir="${src.dir}" - destdir="${build.dir}" deprecation="true"> - <classpath> - <pathelement location="${scala.lib.jar}"/> - <pathelement location="${build.dir}"/> - </classpath> - <include name="@{file}"/> - </scalac> - </sequential> - </for> - </target> - -<!-- =========================================================================== -RUN -============================================================================ --> - - <target name="run" depends="build"> - <pathconvert property="list" pathsep=","> - <path> - <fileset - dir="${src.dir}" - includes="examples/*.scala" - excludes="${excludes.run}" - /> - </path> - <mapper> - <globmapper from="${src.dir}/*" to="*"/> - </mapper> - </pathconvert> - <for list="${list}" param="file"> - <sequential> - <var name="classname" unset="true"/> - <basename property="classname" file="@{file}" suffix=".scala"/> - <echo>Executing Scala program examples.${classname}..</echo> - <java classname="examples.${classname}" fork="true" - output="${build.examples.dir}/${classname}.log" - error="${build.examples.dir}/${classname}.log" - append="true"> - <classpath> - <pathelement location="${scala.lib.jar}"/> - <pathelement location="${build.dir}"/> - </classpath> - </java> - </sequential> - </for> - </target> - -<!-- =========================================================================== -CLEAN -============================================================================ --> - - <macrodef name="remove"> - <attribute name="dir"/> - <sequential> - <delete - dir="@{dir}" - includeemptydirs="yes" - quiet="yes" - failonerror="no" - /> - </sequential> - </macrodef> - - <target name="clean" description="Removes all build examples"> - <remove dir="${build.examples.dir}"/> - </target> - -</project> @@ -1715,29 +1715,32 @@ TODO: <target name="dist.doc" depends="dist.base, docs.done"> - <mkdir dir="${dist.dir}/doc/scala-devel-docs"/> - <copy toDir="${dist.dir}/doc/scala-devel-docs" overwrite="true" flatten="true"> - <file file="${scala-xml-javadoc}"/> - <file file="${scala-parser-combinators-javadoc}"/> + <mkdir dir="${dist.dir}/doc"/> + <mkdir dir="${dist.dir}/doc/licenses"/> + <mkdir dir="${dist.dir}/doc/tools"/> + <copy file="${docs.dir}/LICENSE" toDir="${dist.dir}/doc" overwrite="true"/> + <copy file="${docs.dir}/README" toDir="${dist.dir}/doc" overwrite="true"/> + <copy toDir="${dist.dir}/doc/licenses" overwrite="true"> + <fileset dir="${docs.dir}/licenses"/> + </copy> + <copy toDir="${dist.dir}/doc/tools" overwrite="true"> + <fileset dir="${build-docs.dir}/manual/html"/> </copy> - <copy file="${docs.dir}/LICENSE" toDir="${dist.dir}/doc" overwrite="true"/> - <copy file="${docs.dir}/README" toDir="${dist.dir}/doc" overwrite="true"/> - <mkdir dir="${dist.dir}/doc/scala-devel-docs/api"/> - <copy toDir="${dist.dir}/doc/scala-devel-docs/api" overwrite="true"> + <mkdir dir="${dist.dir}/api"/> + <copy toDir="${dist.dir}/api" overwrite="true"> <fileset dir="${build-docs.dir}/library"/> </copy> - <mkdir dir="${dist.dir}/doc/scala-devel-docs/examples"/> - <copy toDir="${dist.dir}/doc/scala-devel-docs/examples" overwrite="true"> - <fileset dir="${docs.dir}/examples"> - <exclude name="**/*.desired.sha1"/> - </fileset> - </copy> <copy file="${src.dir}/swing/doc/README" - toFile="${dist.dir}/doc/scala-devel-docs/README.scala-swing" - overwrite="true"/> + toFile="${dist.dir}/api/README.scala-swing" overwrite="true"/> + <copy toDir="${dist.dir}/doc/api" overwrite="true" flatten="true"> + <file file="${scala-xml-javadoc}"/> + <file file="${scala-parser-combinators-javadoc}"/> + </copy> + </target> + <target name="dist.man" depends="dist.base, docs.man"> <mkdir dir="${dist.dir}/man"/> <copy toDir="${dist.dir}/man" overwrite="true"> diff --git a/docs/LICENSE b/docs/LICENSE index 446a1a350b..4daedef581 100644 --- a/docs/LICENSE +++ b/docs/LICENSE @@ -1,5 +1,11 @@ +Scala is licensed under the [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause). + +## Scala License + Copyright (c) 2002-2013 EPFL +Copyright (c) 2011-2013 Typesafe, Inc. + All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,3 +31,33 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Other Licenses + +This software includes projects with the following licenses, +which are also included in the `licenses/` directory: + +### [Apache License](http://www.apache.org/licenses/LICENSE-2.0.html) +This license is used by the following third-party libraries: + * jansi + +### [BSD License](http://www.opensource.org/licenses/bsd-license.php) +This license is used by the following third-party libraries: + * jline + +### [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause) +This license is used by the following third-party libraries: + * asm + +### [MIT License](http://www.opensource.org/licenses/MIT) +This license is used by the following third-party libraries: + * jquery + * jquery-ui + * jquery-layout + * sizzle + * tools tooltip + +### Public Domain +The following libraries are freely available in the public domain: + * forkjoin + diff --git a/docs/README b/docs/README index 6af633444d..1d5f553d2e 100644 --- a/docs/README +++ b/docs/README @@ -1,58 +1,36 @@ +Scala Distribution +------------------ -Scala Software Distributions ----------------------------- - -- scala-<major>.<minor>.<patch>.tgz Unix distribution -- scala-<major>.<minor>.<patch>.zip Windows distribution - -The standard distributions require Java 1.5 or above. If you don't -know which version of Java you have, run the command "java -version". +The Scala distribution requires Java 1.6 or above. +Please report bugs at https://issues.scala-lang.org/. +We welcome contributions at https://github.com/scala/scala! Scala Tools ----------- -- fsc Scala offline compiler +- scala Scala interactive interpreter - scalac Scala compiler +- fsc Scala resident compiler - scaladoc Scala API documentation generator -- scala Scala interactive interpreter - scalap Scala classfile decoder Run the command "scalac -help" to display the list of available compiler options. -Unix Installation ------------------ - -Untar the archive. All Scala tools are located in the "bin" directory. -Adding that directory to the PATH variable will make the Scala commands -directly accessible. - -You may test the distribution by running the following commands: - -$ ./bin/scala -scala> Array(4,3,2,1).sorted -res0: Array[Int] = Array(1, 2, 3, 4) - -scala>:quit -$ - - -Windows Installation --------------------- - -Unzip the archive. All Scala tools are located in the "bin" directory. -Adding that directory to the PATH variable will make the Scala commands -directly accessible. +Installation +------------ -On Windows 95/98/Me, you must define the environment variable SCALA_HOME -to point to the home directory of the Scala distribution to run any of -these tools. This can be done by adding the following command to your -AUTOEXEC.BAT file and then rebooting your machine. +Decompress the archive and run the above commands directly from `bin` directory. +We recommend adding the full path of the `bin` directory to the `PATH` +environment variable. -set SCALA_HOME=<install-directory>\scala-<major>.<minor>.<patch> -On Windows NT/2000/XP, you do not need to define any variable in order -for the Scala commands to run correctly. +Licenses +-------- +Scala is licensed under the standard 3-clause BSD license, +included in the distribution as the file `doc/LICENSE`. +The licenses of the software included in the Scala distribution can +be found in the `doc/licenses` directory.
\ No newline at end of file diff --git a/docs/examples/actors/auction.scala b/docs/examples/actors/auction.scala deleted file mode 100644 index c3124c67a9..0000000000 --- a/docs/examples/actors/auction.scala +++ /dev/null @@ -1,131 +0,0 @@ -package examples.actors - -import java.util.Date - -import scala.actors._ -import scala.actors.Actor._ - -/** A simple demonstrator program implementing an online auction service - * The example uses the actor abstraction defined in the API of - * package scala.actors. - */ - -trait AuctionMessage -case class Offer(bid: Int, client: Actor) extends AuctionMessage // make a bid -case class Inquire(client: Actor) extends AuctionMessage // inquire status - -trait AuctionReply -case class Status(asked: Int, expiration: Date) // asked sum, expiration date - extends AuctionReply -case object BestOffer extends AuctionReply // yours is the best offer -case class BeatenOffer(maxBid: Int) extends AuctionReply // offer beaten by maxBid -case class AuctionConcluded(seller: Actor, client: Actor) // auction concluded - extends AuctionReply -case object AuctionFailed extends AuctionReply // failed with no bids -case object AuctionOver extends AuctionReply // bidding is closed - -class AuctionActor(seller: Actor, minBid: Int, closing: Date) extends Actor { - val timeToShutdown = 3000 // msec - val bidIncrement = 10 - - def act() { - var maxBid = minBid - bidIncrement - var maxBidder: Actor = null - - loop { - reactWithin (closing.getTime() - new Date().getTime()) { - - case Offer(bid, client) => - if (bid >= maxBid + bidIncrement) { - if (maxBid >= minBid) - maxBidder ! BeatenOffer(bid) - maxBid = bid - maxBidder = client - client ! BestOffer - } - else - client ! BeatenOffer(maxBid) - - case Inquire(client) => - client ! Status(maxBid, closing) - - case TIMEOUT => - if (maxBid >= minBid) { - val reply = AuctionConcluded(seller, maxBidder) - maxBidder ! reply - seller ! reply - } else { - seller ! AuctionFailed - } - reactWithin(timeToShutdown) { - case Offer(_, client) => client ! AuctionOver - case TIMEOUT => exit() - } - - } - } - } -} - -object auction { - - val random = new scala.util.Random - - val minBid = 100 - val closing = new Date(new Date().getTime() + 4000) - - val seller = Actor.actor { } - val auction = new AuctionActor(seller, minBid, closing) - - def client(i: Int, increment: Int, top: Int) = new Actor { - val name = "Client " + i - def log(msg: String) = Console.println(name + ": " + msg) - var max: Int = _ - var current: Int = 0 - def act() { - log("started") - auction ! Inquire(this) - receive { - case Status(maxBid, _) => - log("status(" + maxBid + ")") - max = maxBid - } - loop { - if (max >= top) { - log("too high for me") - } - else if (current < max) { - current = max + increment - Thread.sleep(1 + random.nextInt(1000)) - auction ! Offer(current, this) - } - - reactWithin(3000) { - case BestOffer => - log("bestOffer(" + current + ")") - - case BeatenOffer(maxBid) => - log("beatenOffer(" + maxBid + ")") - max = maxBid - - case AuctionConcluded(seller, maxBidder) => - log("auctionConcluded"); exit() - - case AuctionOver => - log("auctionOver"); exit() - - case TIMEOUT => - exit() - } - } - } - } - - def main(args: Array[String]) { - seller.start() - auction.start() - client(1, 20, 200).start() - client(2, 10, 300).start() - } - -} diff --git a/docs/examples/actors/boundedbuffer.scala b/docs/examples/actors/boundedbuffer.scala deleted file mode 100644 index c65bb7719c..0000000000 --- a/docs/examples/actors/boundedbuffer.scala +++ /dev/null @@ -1,37 +0,0 @@ -package examples.actors - -import scala.actors.Actor._ - -object boundedbuffer { - class BoundedBuffer[T](N: Int)(implicit m: Manifest[T]) { - private case class Put(x: T) - private case object Get - private case object Stop - - private val buffer = actor { - val buf = new Array[T](N) - var in, out, n = 0 - loop { - react { - case Put(x) if n < N => - buf(in) = x; in = (in + 1) % N; n += 1; reply() - case Get if n > 0 => - val r = buf(out); out = (out + 1) % N; n -= 1; reply(r) - case Stop => - reply(); exit("stopped") - } - } - } - - def put(x: T) { buffer !? Put(x) } - def get: T = (buffer !? Get).asInstanceOf[T] - def stop() { buffer !? Stop } - } - - def main(args: Array[String]) { - val buf = new BoundedBuffer[Int](1) - buf.put(42) - println("" + buf.get) - buf.stop() - } -} diff --git a/docs/examples/actors/channels.scala b/docs/examples/actors/channels.scala deleted file mode 100644 index 3c0dbf232d..0000000000 --- a/docs/examples/actors/channels.scala +++ /dev/null @@ -1,32 +0,0 @@ -package examples.actors - -import scala.actors._ -import scala.actors.Actor._ - -object channels extends Application { - case class Msg(ch1: Channel[Int], ch2: Channel[String]) - - val a = actor { - val Ch1 = new Channel[Int] - val Ch2 = new Channel[String] - - b ! Msg(Ch1, Ch2) - - val ICh1 = Ch1.asInstanceOf[InputChannel[Int]] - val ICh2 = Ch2.asInstanceOf[InputChannel[String]] - - react { - case ICh1 ! (x: Int) => - val r = x + 21 - println("result: "+r) - case ICh2 ! y => - println("received: "+y) - } - } - - val b = actor { - react { - case Msg(ch1, ch2) => ch1 ! 21 - } - } -} diff --git a/docs/examples/actors/fringe.scala b/docs/examples/actors/fringe.scala deleted file mode 100644 index 2026628cb3..0000000000 --- a/docs/examples/actors/fringe.scala +++ /dev/null @@ -1,82 +0,0 @@ -package examples.actors - -import scala.actors.Actor._ -import scala.actors.{Channel, OutputChannel} - -/** - @author Philipp Haller - @version 1.1, 09/21/2007 - */ -object fringe extends Application { - - abstract class Tree - case class Node(left: Tree, right: Tree) extends Tree - case class Leaf(v: Int) extends Tree - - case class CompareFringe(t1: Tree, t2: Tree) - case class ComputeFringe(t1: Tree, atoms: OutputChannel[Option[Leaf]]) - case class Equal(atom1: Option[Leaf], atom2: Option[Leaf]) - case class Extract(tree: Tree) - - val comparator = actor { - val extractor1 = actor(extractorBehavior()) - val extractor2 = actor(extractorBehavior()) - val ch1 = new Channel[Option[Leaf]] - val ch2 = new Channel[Option[Leaf]] - loop { - react { - case CompareFringe(tree1, tree2) => - extractor1 ! ComputeFringe(tree1, ch1) - extractor2 ! ComputeFringe(tree2, ch2) - self ! Equal(ch1.?, ch2.?) - - case Equal(atom1, atom2) => - if (atom1 == atom2) atom1 match { - case None => - println("same fringe") - exit() - case _ => - self ! Equal(ch1.?, ch2.?) - } else { - println("fringes differ") - exit() - } - } - } - } - - val extractorBehavior = () => { - var output: OutputChannel[Option[Leaf]] = null - loop { - react { - case ComputeFringe(tree, leafSink) => - output = leafSink - self ! Extract(tree) - - case Extract(tree) => tree match { - case atom @ Leaf(_) => - output ! Some(atom) - sender ! 'Continue - - case Node(left, right) => - val outer = self - val outerCont = sender - val cont = actor { - react { - case 'Continue => - outer.send(Extract(right), outerCont) - } - } - self.send(Extract(left), cont) - } - - case 'Continue => - output ! None - exit() - } - } - } - - comparator ! CompareFringe(Node(Leaf(5), Node(Leaf(7), Leaf(3))), - Node(Leaf(5), Node(Leaf(7), Leaf(3)))) -} diff --git a/docs/examples/actors/links.scala b/docs/examples/actors/links.scala deleted file mode 100644 index 373e6b07ce..0000000000 --- a/docs/examples/actors/links.scala +++ /dev/null @@ -1,47 +0,0 @@ -package examples.actors - -import scala.actors.{Actor, Exit} -import scala.actors.Actor._ - -object links extends Application { - - case object Stop - - actor { - val start = link(p(2)) - start ! Stop - } - - def p(n: Int): Actor = - if (n == 0) top1() - else top(p(n-1), n) - - def top(a: Actor, n: Int): Actor = actor { - println("starting actor " + n + " (" + self + ")") - self.trapExit = true - link(a) - loop { - receive { - case ex @ Exit(from, reason) => - println("Actor " + n + " received " + ex) - exit('finished) - case any => { - println("Actor " + n + " received " + any) - a ! any - } - } - } - } - - def top1(): Actor = actor { - println("starting last actor" + " (" + self + ")") - receive { - case Stop => - println("Last actor now exiting") - exit('abnormal) - case any => - println("Last actor received " + any) - top1() - } - } -} diff --git a/docs/examples/actors/looping.scala b/docs/examples/actors/looping.scala deleted file mode 100644 index 1ce2e2e5e8..0000000000 --- a/docs/examples/actors/looping.scala +++ /dev/null @@ -1,26 +0,0 @@ -package examples.actors - -import scala.actors.Actor._ - -object looping extends Application { - case object A - - val a = actor { - var cnt = 0 - loop { - react { - case A => - cnt += 1 - if (cnt % 2 != 0) continue - if (cnt < 10) - println("received A") - else { - println("received last A") - exit() - } - } - } - } - - for (i <- 0 until 10) a ! A -} diff --git a/docs/examples/actors/message.scala b/docs/examples/actors/message.scala deleted file mode 100644 index d385543470..0000000000 --- a/docs/examples/actors/message.scala +++ /dev/null @@ -1,40 +0,0 @@ -package examples.actors - -import scala.actors.{Actor, Scheduler} -import scala.actors.Actor._ -import scala.actors.scheduler.SingleThreadedScheduler - -object message { - def main(args: Array[String]) { - val n = try { args(0).toInt } - catch { - case _ => - println("Usage: examples.actors.message <n>") - Predef.exit - } - val nActors = 500 - val finalSum = n * nActors - Scheduler.impl = new SingleThreadedScheduler - - def beh(next: Actor, sum: Int) { - react { - case value: Int => - val j = value + 1; val nsum = sum + j - if (next == null && nsum >= n * j) - println(nsum) - else { - if (next != null) next ! j - if (nsum < n * j) beh(next, nsum) - } - } - } - - def actorChain(i: Int, a: Actor): Actor = - if (i > 0) actorChain(i-1, actor(beh(a, 0))) else a - - val firstActor = actorChain(nActors, null) - var i = n; while (i > 0) { firstActor ! 0; i -= 1 } - - Scheduler.shutdown() - } -} diff --git a/docs/examples/actors/pingpong.scala b/docs/examples/actors/pingpong.scala deleted file mode 100644 index c355bee244..0000000000 --- a/docs/examples/actors/pingpong.scala +++ /dev/null @@ -1,61 +0,0 @@ -package examples.actors - -import scala.actors.Actor -import scala.actors.Actor._ - -case object Ping -case object Pong -case object Stop - -/** - * Ping pong example. - * - * @author Philipp Haller - * @version 1.1 - */ -object pingpong extends App { - val pong = new Pong - val ping = new Ping(100000, pong) - ping.start - pong.start -} - -class Ping(count: Int, pong: Actor) extends Actor { - def act() { - var pingsLeft = count - 1 - pong ! Ping - loop { - react { - case Pong => - if (pingsLeft % 1000 == 0) - println("Ping: pong") - if (pingsLeft > 0) { - pong ! Ping - pingsLeft -= 1 - } else { - println("Ping: stop") - pong ! Stop - exit() - } - } - } - } -} - -class Pong extends Actor { - def act() { - var pongCount = 0 - loop { - react { - case Ping => - if (pongCount % 1000 == 0) - println("Pong: ping "+pongCount) - sender ! Pong - pongCount += 1 - case Stop => - println("Pong: stop") - exit() - } - } - } -} diff --git a/docs/examples/actors/producers.scala b/docs/examples/actors/producers.scala deleted file mode 100644 index 80e5ae33d3..0000000000 --- a/docs/examples/actors/producers.scala +++ /dev/null @@ -1,114 +0,0 @@ -package examples.actors - -import scala.actors.Actor -import scala.actors.Actor._ - -abstract class Producer[T] { - - /** A signal that the next value should be produced. */ - private val Next = new Object - - /** A label for an undefined state of the iterators. */ - private val Undefined = new Object - - /** A signal to stop the coordinator. */ - private val Stop = new Object - - protected def produce(x: T) { - coordinator ! Some(x) - receive { case Next => } - } - - protected def produceValues: Unit - - def iterator = new Iterator[T] { - private var current: Any = Undefined - private def lookAhead = { - if (current == Undefined) current = coordinator !? Next - current - } - - def hasNext: Boolean = lookAhead match { - case Some(x) => true - case None => { coordinator ! Stop; false } - } - - def next: T = lookAhead match { - case Some(x) => current = Undefined; x.asInstanceOf[T] - } - } - - private val coordinator: Actor = actor { - loop { - react { - case Next => - producer ! Next - reply { - receive { case x: Option[_] => x } - } - case Stop => - exit('stop) - } - } - } - - private val producer: Actor = actor { - receive { - case Next => - produceValues - coordinator ! None - } - } -} - -object producers extends Application { - - class Tree(val left: Tree, val elem: Int, val right: Tree) - def node(left: Tree, elem: Int, right: Tree): Tree = new Tree(left, elem, right) - def node(elem: Int): Tree = node(null, elem, null) - - def tree = node(node(node(3), 4, node(6)), 8, node(node(9), 10, node(11))) - - class PreOrder(n: Tree) extends Producer[Int] { - def produceValues = traverse(n) - def traverse(n: Tree) { - if (n != null) { - produce(n.elem) - traverse(n.left) - traverse(n.right) - } - } - } - - class PostOrder(n: Tree) extends Producer[Int] { - def produceValues = traverse(n) - def traverse(n: Tree) { - if (n != null) { - traverse(n.left) - traverse(n.right) - produce(n.elem) - } - } - } - - class InOrder(n: Tree) extends Producer[Int] { - def produceValues = traverse(n) - def traverse(n: Tree) { - if (n != null) { - traverse(n.left) - produce(n.elem) - traverse(n.right) - } - } - } - - actor { - print("PreOrder:") - for (x <- new PreOrder(tree).iterator) print(" "+x) - print("\nPostOrder:") - for (x <- new PostOrder(tree).iterator) print(" "+x) - print("\nInOrder:") - for (x <- new InOrder(tree).iterator) print(" "+x) - print("\n") - } -} diff --git a/docs/examples/actors/seq.scala b/docs/examples/actors/seq.scala deleted file mode 100644 index 816c969cb6..0000000000 --- a/docs/examples/actors/seq.scala +++ /dev/null @@ -1,15 +0,0 @@ -package examples.actors - -object seq extends Application { - import scala.actors.Actor._ - val a = actor { - { react { - case 'A => println("received 1st message") - }; () - } andThen react { - case 'A => println("received 2nd message") - } - } - a ! 'A - a ! 'A -} diff --git a/docs/examples/boundedbuffer.scala b/docs/examples/boundedbuffer.scala deleted file mode 100644 index 359bfd8d06..0000000000 --- a/docs/examples/boundedbuffer.scala +++ /dev/null @@ -1,46 +0,0 @@ -package examples - -object boundedbuffer { - - import concurrent.ops._ - - class BoundedBuffer[A](N: Int)(implicit m: ClassManifest[A]) { - var in, out, n = 0 - val elems = new Array[A](N) - - def await(cond: => Boolean) = while (!cond) { wait() } - - def put(x: A) = synchronized { - await (n < N) - elems(in) = x; in = (in + 1) % N; n += 1 - if (n == 1) notifyAll() - } - - def get: A = synchronized { - await (n != 0) - val x = elems(out); out = (out + 1) % N ; n -= 1 - if (n == N - 1) notifyAll() - x - } - } - - def kill(delay: Int) = new java.util.Timer().schedule( - new java.util.TimerTask { - override def run() = { - println("[killed]") - System.exit(0) - } - }, - delay) // in milliseconds - - def main(args: Array[String]) { - val buf = new BoundedBuffer[String](10) - var cnt = 0 - def produceString = { cnt += 1; cnt.toString() } - def consumeString(ss: String) = println(ss) - spawn { while (true) { val ssss = produceString; buf.put(ssss) } } - spawn { while (true) { val s = buf.get; consumeString(s) } } - kill(1000) - } - -} diff --git a/docs/examples/computeserver.scala b/docs/examples/computeserver.scala deleted file mode 100644 index 788be284d1..0000000000 --- a/docs/examples/computeserver.scala +++ /dev/null @@ -1,54 +0,0 @@ -package examples - -import concurrent._, concurrent.ops._ - -class ComputeServer(n: Int) { - - private trait Job { - type t - def task: t - def ret(x: t): Unit - } - - private val openJobs = new Channel[Job]() - - private def processor(i: Int) { - while (true) { - val job = openJobs.read - println("read a job") - job.ret(job.task) - } - } - - def future[a](p: => a): () => a = { - val reply = new SyncVar[a]() - openJobs.write{ - new Job { - type t = a - def task = p - def ret(x: a) = reply.set(x) - } - } - () => reply.get - } - - //spawn(replicate(0, n) { processor }) - spawn((0 until n).par foreach { processor }) -} - -object computeserver extends App { - - def kill(delay: Int) = new java.util.Timer().schedule( - new java.util.TimerTask { - override def run() = { - println("[killed]") - sys exit 0 - } - }, - delay) // in milliseconds - - val server = new ComputeServer(1) - val f = server.future(42) - println(f()) - kill(10000) -} diff --git a/docs/examples/expressions/expressions-current.scala b/docs/examples/expressions/expressions-current.scala deleted file mode 100644 index 660a417c11..0000000000 --- a/docs/examples/expressions/expressions-current.scala +++ /dev/null @@ -1,68 +0,0 @@ -package examples.expressions - -class Ref[a](var elem:a) {} - -abstract class Lang { - trait Visitor { - def caseNum(n: int): unit - } - - abstract class Exp { - def visit(v: visitor): unit - } - - type visitor <: Visitor - - class Num(n: int) extends Exp { - def visit(v: visitor): unit = v.caseNum(n) - } - - class Eval(result: Ref[int]) requires visitor extends Visitor { - def caseNum(n: int) = result.elem = n - } -} - -abstract class Lang2 extends Lang { - trait Visitor2 extends Visitor { - def casePlus(left: Exp, right: Exp): unit - } - - type visitor <: Visitor2 - - class Plus(l: Exp, r: Exp) extends Exp { - def visit(v: visitor): unit = v.casePlus(l, r) - } - - // class Eval2(result: Ref[int]): visitor extends Eval(result) with Visitor2 { - class Eval2(result: Ref[int]) requires visitor extends Eval(result) with Visitor2 { - def casePlus(l: Exp, r: Exp) = - result.elem = { l.visit(this); result.elem } + { r.visit(this); result.elem } - } - - class Show2(result: Ref[String]) requires visitor extends Visitor2 { - def caseNum(n: int) = result.elem = n.toString() - def casePlus(l: Exp, r: Exp) = - result.elem = - "(" + { l.visit(this); result.elem } + - "+" + { r.visit(this); result.elem } + ")" - } -} - -object Main { - def main(args: Array[String]): unit = { - //val l1 = new Lang { type visitor = Visitor } // not yet implemented - object l1 extends Lang { type visitor = Visitor } // workaround - val e1: l1.Exp = new l1.Num(42) - val iref = new Ref(0) - Console.println("eval: " + { e1.visit(new l1.Eval(iref)); iref.elem }) - - //val l2 = new Lang2 { type visitor = Visitor2 } // not yet implemented - object l2 extends Lang2 { type visitor = Visitor2 } // workaround - val e2: l2.Exp = new l2.Plus(new l2.Num(5), new l2.Num(37)) - val sref = new Ref("") - Console.println("eval: " + { e2.visit(new l2.Eval2(iref)); iref.elem }) - Console.println("show: " + { e2.visit(new l2.Show2(sref)); sref.elem }) - e1.visit(new l1.Eval(iref)) - e2.visit(new l2.Show2(sref)) - } -} diff --git a/docs/examples/fors.scala b/docs/examples/fors.scala deleted file mode 100644 index 29616b61b1..0000000000 --- a/docs/examples/fors.scala +++ /dev/null @@ -1,112 +0,0 @@ -package examples - -import scala.xml._ - - -object fors { - - val e = Node.NoAttributes - - class Person(_name: String, _age: Int) { - val name = _name - val age = _age - } - - def printOlderThan20(xs: Seq[Person]): Iterator[String] = - printOlderThan20(xs.iterator) - - def printOlderThan20(xs: Iterator[Person]): Iterator[String] = - for (p <- xs if p.age > 20) yield p.name - - val persons = List( - new Person("John", 40), - new Person("Richard", 68) - ) - - def divisors(n: Int): List[Int] = - for (i <- List.range(1, n+1) if n % i == 0) yield i - - def isPrime(n: Int) = divisors(n).length == 2 - - def findNums(n: Int): Iterable[(Int, Int)] = - for (i <- 1 until n; - j <- 1 until (i-1); - if isPrime(i+j)) yield (i, j) - - def sum(xs: List[Double]): Double = - xs.foldLeft(0.0) { (x, y) => x + y } - - def scalProd(xs: List[Double], ys: List[Double]) = - sum(for((x, y) <- xs zip ys) yield x * y) - - type Lst = List[Any] - - val prefix = null - val scope = TopScope - - val books = List( - Elem(prefix, "book", e, scope, - Elem(prefix, "title", e, scope, - Text("Structure and Interpretation of Computer Programs")), - Elem(prefix, "author", e, scope, - Text("Abelson, Harald")), - Elem(prefix, "author", e, scope, - Text("Sussman, Gerald J."))), - Elem(prefix, "book", e, scope, - Elem(prefix, "title", e, scope, - Text("Principles of Compiler Design")), - Elem(prefix, "author", e, scope, - Text("Aho, Alfred")), - Elem(prefix, "author", e, scope, - Text("Ullman, Jeffrey"))), - Elem(prefix, "book", e, scope, - Elem(prefix, "title", e, scope, - Text("Programming in Modula-2")), - Elem(prefix, "author", e, scope, - Text("Wirth, Niklaus"))) - ) - - def findAuthor(books: Lst) = - for (Elem(_, "book", _, _, book @ _*) <- books; - Elem(_, "title", _, _, Text(title)) <- book.toList; - if (title indexOf "Program") >= 0; - Elem(_, "author", _, _, Text(author)) <- List(book)) yield author - - for (Elem(_, "book", _, _, book @ _*) <- books; - Elem(_, "author", _, _, Text(author)) <- book.toList; - if author startsWith "Ullman"; - Elem(_, "title", _, _, Text(title)) <- List(book)) yield title - - removeDuplicates( - for (Elem(_, "book", _, _, b1 @ _* ) <- books; - Elem(_, "book", _, _, b2 @ _*) <- books; - if b1 != b2; - Elem(_, "author", _, _, Text(a1)) <- b1.toList; - Elem(_, "author", _, _, Text(a2)) <- b2.toList; - if a1 == a2) yield (a1, a2)) - - def removeDuplicates[a](xs: List[a]): List[a] = - if (xs.isEmpty) - xs - else - xs.head :: removeDuplicates(for (x <- xs.tail if x != xs.head) yield x) - - def main(args: Array[String]) { - print("Persons over 20:") - printOlderThan20(persons) foreach { x => print(" " + x) } - println - - println("divisors(34) = " + divisors(34)) - - print("findNums(15) ="); - findNums(15) foreach { x => print(" " + x); } - println - - val xs = List(3.5, 5.0, 4.5) - println("average(" + xs + ") = " + sum(xs) / xs.length) - - val ys = List(2.0, 1.0, 3.0) - println("scalProd(" + xs + ", " + ys +") = " + scalProd(xs, ys)) - } - -} diff --git a/docs/examples/futures.scala b/docs/examples/futures.scala deleted file mode 100644 index e05b6b330e..0000000000 --- a/docs/examples/futures.scala +++ /dev/null @@ -1,17 +0,0 @@ -package examples - -import concurrent.ops._ - -object futures { - def someLengthyComputation = 1 - def anotherLengthyComputation = 2 - def f(x: Int) = x + x - def g(x: Int) = x * x - - def main(args: Array[String]) { - val x = future(someLengthyComputation) - anotherLengthyComputation - val y = f(x()) + g(x()) - println(y) - } -} diff --git a/docs/examples/gadts.scala b/docs/examples/gadts.scala deleted file mode 100644 index d2792f4ada..0000000000 --- a/docs/examples/gadts.scala +++ /dev/null @@ -1,22 +0,0 @@ -package examples - -object gadts extends Application { - - abstract class Term[T] - case class Lit(x: Int) extends Term[Int] - case class Succ(t: Term[Int]) extends Term[Int] - case class IsZero(t: Term[Int]) extends Term[Boolean] - case class If[T](c: Term[Boolean], - t1: Term[T], - t2: Term[T]) extends Term[T] - - def eval[T](t: Term[T]): T = t match { - case Lit(n) => n - case Succ(u) => eval(u) + 1 - case IsZero(u) => eval(u) == 0 - case If(c, u1, u2) => eval(if (eval(c)) u1 else u2) - } - println( - eval(If(IsZero(Lit(1)), Lit(41), Succ(Lit(41))))) -} - diff --git a/docs/examples/iterators.scala b/docs/examples/iterators.scala deleted file mode 100644 index 9ddb141d61..0000000000 --- a/docs/examples/iterators.scala +++ /dev/null @@ -1,28 +0,0 @@ -package examples - -object iterators { - - def Array(elems: Double*): Array[Double] = { - val ar = new Array[Double](elems.length) - for (i <- 0 until elems.length) - ar(i) = elems(i) - ar - } - - def printArray(xs: Array[Double]) = - xs.iterator foreach { x => println(x) } - - def findGreater(xs: Array[Double], limit: Double) = - xs.iterator - .zip(Iterator.from(0)) - .filter{case (x, i) => x > limit } - .map{case (x, i) => i} - - def main(args: Array[String]) { - val ar = Array/*[Double]*/(6, 2, 8, 5, 1) - printArray(ar) - println("Elements greater than 3.0:") - findGreater(ar, 3.0) foreach { x => Console.println(ar(x)) } - } - -} diff --git a/docs/examples/jolib/Ref.scala b/docs/examples/jolib/Ref.scala deleted file mode 100644 index 099a3c2df2..0000000000 --- a/docs/examples/jolib/Ref.scala +++ /dev/null @@ -1,55 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package examples.jolib; -/* -import concurrent.SyncVar; -import concurrent.jolib._; - -class Ref[a](init: a) extends Join { - - object get extends Synchr[a](this) { case class C() extends SyncVar[a]; } - object set extends Synchr[unit](this) { case class C(x: a) extends SyncVar[unit]; } - object state extends Asynchr(this) { case class C(x: a); } - - rules ( - (List(get, state), { case List(g @ get.C(), state.C(x) ) => - { g.set(x); state(state.C(x)) } }), - (List(set, state), { case List(s @ set.C(x), state.C(y) ) => - { s.set(()); state(state.C(x)) } }) - ); - - state(state.C(init)); - - def Get: a = get(get.C()); - def Set(x: a): unit = set(set.C(x)); -} -*/ -object RefTest { - - def main(args: Array[String]) = { - System.out.println("Started."); -/* - concurrent.ops.spawn({ - val r1 = new Ref(0); - System.out.println("Reference r1 created."); - System.out.println("Value r1 (first time) = " + r1.Get); - r1.Set(42); - System.out.println("Value r1 (second time) = " + r1.Get); - }); - concurrent.ops.spawn({ - val r2 = new Ref(100); - System.out.println("Reference r2 created."); - System.out.println("Value r2 (first time) = " + r2.Get); - r2.Set(89); - System.out.println("Value r2 (second time) = " + r2.Get); - }); -*/ - } - -} diff --git a/docs/examples/jolib/parallelOr.scala b/docs/examples/jolib/parallelOr.scala deleted file mode 100644 index a0305c56bf..0000000000 --- a/docs/examples/jolib/parallelOr.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package examples.jolib; -/* -import concurrent.jolib._; -import concurrent.SyncVar; - -/** Implementation in the join-calculus of a parallel OR. */ -object or extends Join { - - object res extends Synchr[boolean](this) { case class C() extends SyncVar[boolean] }; - object res1 extends Asynchr(this) { case class C(b: boolean); } - object res2 extends Asynchr(this) { case class C(b: boolean); } - object res1False extends Synchr[boolean](this) { case class C() extends SyncVar[boolean] }; - object res2False extends Synchr[boolean](this) { case class C() extends SyncVar[boolean] }; - - rules( - (List(res, res1), { case List(r @ res.C(), res1.C(b)) => - if (b) r.set(b) else r.set(res1False(res1False.C())) }), - - (List(res, res2), { case List(r @ res.C(), res2.C(b)) => - if (b) r.set(b) else r.set(res2False(res2False.C())) }), - - (List(res1False, res2), { case List(r @ res1False.C(), res2.C(b)) => - r.set(b) }), - - (List(res2False, res1), { case List(r @ res2False.C(), res1.C(b)) => - r.set(b) }) - ); - - def apply(b1: => boolean, b2: => boolean): boolean = { - concurrent.ops.spawn(res1(res1.C(b1))); - concurrent.ops.spawn(res2(res2.C(b2))); - res(res.C()) - } -} -*/ -object parallelOr { - - def main(args: Array[String]): unit = { - def loop: boolean = { while (true) {}; true }; -/* - System.out.println("true || true = " + or(true, true)); - System.out.println("false || false = " + or(false, false)); - System.out.println("false || true = " + or(false, true)); - System.out.println("true || false = " + or(true, false)); - System.out.println("true || loop = " + or(true, loop)); - System.out.println("loop || true = " + or(loop, true)); -*/ - } - -} diff --git a/docs/examples/maps.scala b/docs/examples/maps.scala deleted file mode 100644 index d545b50ab9..0000000000 --- a/docs/examples/maps.scala +++ /dev/null @@ -1,187 +0,0 @@ -package examples - -object maps { - - import scala.collection.immutable._ - - trait MapStruct[kt, vt] { - trait Map extends Function1[kt, vt] { - def extend(key: kt, value: vt): Map - def remove(key: kt): Map - def domain: Stream[kt] - def range: Stream[vt] - } - type map <: Map - val empty: map - } - - class AlgBinTree[kt >: Null <: Ordered[kt], vt >: Null <: AnyRef]() extends MapStruct[kt, vt] { - type map = AlgMap - - val empty: AlgMap = Empty() - - private case class Empty() extends AlgMap {} - private case class Node(key: kt, value: vt, l: map, r: map) extends AlgMap {} - - trait AlgMap extends Map { - def apply(key: kt): vt = this match { - case Empty() => null - case Node(k, v, l, r) => - if (key < k) l.apply(key) - else if (key > k) r.apply(key) - else v - } - - def extend(key: kt, value: vt): map = this match { - case Empty()=> Node(key, value, empty, empty) - case Node(k, v, l, r) => - if (key < k) Node(k, v, l.extend(key, value), r) - else if (key > k) Node(k, v, l, r.extend(key, value)) - else Node(k, value, l, r) - } - - def remove(key: kt): map = this match { - case Empty()=> empty - case Node(k, v, l, r) => - if (key < k) Node(k, v, l.remove(key), r) - else if (key > k) Node(k, v, l, r.remove(key)) - else if (l == empty) r - else if (r == empty) l - else { - val midKey = r.domain.head - Node(midKey, r.apply(midKey), l, r.remove(midKey)) - } - } - - def domain: Stream[kt] = this match { - case Empty()=> Stream.empty - case Node(k, v, l, r) => l.domain append Stream.cons(k, r.domain) - } - - def range: Stream[vt] = this match { - case Empty()=> Stream.empty - case Node(k, v, l, r) => l.range append Stream.cons(v, r.range) - } - } - } - - class OOBinTree[kt >: Null <: Ordered[kt], vt >: Null <: AnyRef]() extends MapStruct[kt, vt] { - type map = OOMap - - trait OOMap extends Map { - def apply(key: kt): vt - def extend(key: kt, value: vt): map - def remove(key: kt): map - def domain: Stream[kt] - def range: Stream[vt] - } - val empty: OOMap = new OOMap { - def apply(key: kt): vt = null - def extend(key: kt, value: vt) = new Node(key, value, empty, empty) - def remove(key: kt) = empty - def domain: Stream[kt] = Stream.empty - def range: Stream[vt] = Stream.empty - } - private class Node(k: kt, v: vt, l: map, r: map) extends OOMap { - def apply(key: kt): vt = - if (key < k) l.apply(key) - else if (key > k) r.apply(key) - else v; - def extend(key: kt, value: vt): map = - if (key < k) new Node(k, v, l.extend(key, value), r) - else if (key > k) new Node(k, v, l, r.extend(key, value)) - else new Node(k, value, l, r) - def remove(key: kt): map = - if (key < k) new Node(k, v, l.remove(key), r) - else if (key > k) new Node(k, v, l, r.remove(key)) - else if (l == empty) r - else if (r == empty) l - else { - val midKey = r.domain.head - new Node(midKey, r(midKey), l, r.remove(midKey)) - } - def domain: Stream[kt] = l.domain append Stream.cons(k, r.domain) - def range: Stream[vt] = l.range append Stream.cons(v, r.range) - } - } - - class MutBinTree[kt >: Null <: Ordered[kt], vt >: Null <: AnyRef]() extends MapStruct[kt, vt] { - type map = MutMap - class MutMap(key: kt, value: vt) extends Map { - val k = key - var v = value - var l, r = empty - - def apply(key: kt): vt = - if (this == empty) null - else if (key < k) l.apply(key) - else if (key > k) r.apply(key) - else v - - def extend(key: kt, value: vt): map = - if (this == empty) new MutMap(key, value) - else { - if (key < k) l = l.extend(key, value) - else if (key > k) r = r.extend(key, value) - else v = value - this - } - - def remove(key: kt): map = - if (this == empty) this - else if (key < k) { l = l.remove(key); this } - else if (key > k) { r = r.remove(key); this } - else if (l == empty) r - else if (r == empty) l - else { - var mid = r - while (!(mid.l == empty)) { mid = mid.l } - mid.r = r.remove(mid.k) - mid.l = l - mid - } - - def domain: Stream[kt] = - if (this == empty) Stream.empty - else l.domain append Stream.cons(k, r.domain) - - def range: Stream[vt] = - if (this == empty) Stream.empty - else l.range append Stream.cons(v, r.range) - } - val empty = new MutMap(null, null) - } - - class Date(y: Int, m: Int, d: Int) extends Ordered[Date] { - def year = y - def month = m - def day = d - - def compare(other: Date): Int = - if (year == other.year && - month == other.month && - day == other.day) - 0 - else if (year < other.year || - year == other.year && month < other.month || - month == other.month && day < other.day) - -1 - else - 1 - - override def equals(that: Any): Boolean = - that.isInstanceOf[Date] && { - val o = that.asInstanceOf[Date]; - day == o.day && month == o.month && year == o.year - } - } - - def main(args: Array[String]) { - val t = new OOBinTree[Date, String]() - () - } - -} - - - diff --git a/docs/examples/monads/callccInterpreter.scala b/docs/examples/monads/callccInterpreter.scala deleted file mode 100644 index b5008c4c1b..0000000000 --- a/docs/examples/monads/callccInterpreter.scala +++ /dev/null @@ -1,86 +0,0 @@ -object callccInterpreter { - - def id[a](x: a) = x - - type Answer = Value; - - case class M[A](in: (A => Answer) => Answer) { - def bind[B](k: A => M[B]) = M[B](c => in (a => k(a) in c)); - def map[B](f: A => B): M[B] = bind(x => unitM(f(x))); - def flatMap[B](f: A => M[B]): M[B] = bind(f); - } - - def unitM[A](a: A) = M[A](c => c(a)); - - def showM(m: M[Value]): String = (m in id).toString(); - - def callCC[A](h: (A => M[A]) => M[A]) = - M[A](c => h(a => M[A](d => c(a))) in c); - - type Name = String; - - trait Term; - case class Var(x: Name) extends Term; - case class Con(n: Int) extends Term; - case class Add(l: Term, r: Term) extends Term; - case class Lam(x: Name, body: Term) extends Term; - case class App(fun: Term, arg: Term) extends Term; - case class Ccc(x: Name, t: Term) extends Term; - - trait Value; - case object Wrong extends Value { - override def toString() = "wrong" - } - case class Num(n: Int) extends Value { - override def toString() = n.toString(); - } - case class Fun(f: Value => M[Value]) extends Value { - override def toString() = "<function>" - } - - type Environment = List[Tuple2[Name, Value]]; - - def lookup(x: Name, e: Environment): M[Value] = e match { - case List() => unitM(Wrong) - case (y, b) :: e1 => if (x == y) unitM(b) else lookup(x, e1) - } - - def add(a: Value, b: Value): M[Value] = (a, b) match { - case (Num(m), Num(n)) => unitM(Num(m + n)) - case _ => unitM(Wrong) - } - - def apply(a: Value, b: Value): M[Value] = a match { - case Fun(k) => k(b) - case _ => unitM(Wrong) - } - - def interp(t: Term, e: Environment): M[Value] = t match { - case Var(x) => lookup(x, e) - case Con(n) => unitM(Num(n)) - case Add(l, r) => for (a <- interp(l, e); - b <- interp(r, e); - c <- add(a, b)) - yield c - case Lam(x, t) => unitM(Fun(a => interp(t, (x, a) :: e))) - case App(f, t) => for (a <- interp(f, e); - b <- interp(t, e); - c <- apply(a, b)) - yield c - case Ccc(x, t) => callCC(k => interp(t, (x, Fun(k)) :: e)) - } - - def test(t: Term): String = - showM(interp(t, List())); - - val term0 = App(Lam("x", Add(Var("x"), Var("x"))), Add(Con(10), Con(11))); - val term1 = App(Con(1), Con(2)); - val term2 = Add(Con(1), Ccc("k", Add(Con(2), App(Var("k"), Con(4))))); - - def main(args: Array[String]) = { - System.out.println(test(term0)); - System.out.println(test(term1)); - System.out.println(test(term2)); - } -} - diff --git a/docs/examples/monads/directInterpreter.scala b/docs/examples/monads/directInterpreter.scala deleted file mode 100644 index d8ca8ccfa7..0000000000 --- a/docs/examples/monads/directInterpreter.scala +++ /dev/null @@ -1,55 +0,0 @@ -object directInterpreter { - - type Name = String; - - trait Term; - case class Var(x: Name) extends Term; - case class Con(n: Int) extends Term; - case class Add(l: Term, r: Term) extends Term; - case class Lam(x: Name, body: Term) extends Term; - case class App(fun: Term, arg: Term) extends Term; - - trait Value; - case object Wrong extends Value; - case class Num(n: Int) extends Value; - case class Fun(f: Value => Value)extends Value; - - def showval(v: Value): String = v match { - case Wrong => "<wrong>" - case Num(n) => n.toString() - case Fun(f) => "<function>" - } - - type Environment = List[Tuple2[Name, Value]]; - - def lookup(x: Name, e: Environment): Value = e match { - case List() => Wrong - case (y, b) :: e1 => if (x == y) b else lookup(x, e1) - } - - def add(a: Value, b: Value): Value = (a, b) match { - case (Num(m), Num(n)) => Num(m + n) - case _ => Wrong - } - - def apply(a: Value, b: Value) = a match { - case Fun(k) => k(b) - case _ => Wrong - } - - def interp(t: Term, e: Environment): Value = t match { - case Var(x) => lookup(x, e) - case Con(n) => Num(n) - case Add(l, r) => add(interp(l, e), interp(r, e)) - case Lam(x, t) => Fun(a => interp(t, (x, a) :: e)) - case App(f, t) => apply(interp(f, e), interp(t, e)) - } - - def test(t: Term): String = - showval(interp(t, List())); - - val term0 = App(Lam("x", Add(Var("x"), Var("x"))), Add(Con(10), Con(11))); - - def main(args: Array[String]) = - System.out.println(test(term0)); -} diff --git a/docs/examples/monads/errorInterpreter.scala b/docs/examples/monads/errorInterpreter.scala deleted file mode 100644 index c15e1041e2..0000000000 --- a/docs/examples/monads/errorInterpreter.scala +++ /dev/null @@ -1,86 +0,0 @@ -object errorInterpreter { - - trait M[A] { - def show: String - def bind[B](k: A => M[B]): M[B] - def map[B](f: A => B): M[B] = bind(x => unitM(f(x))) - def flatMap[B](f: A => M[B]): M[B] = bind(f) - } - - def unitM[A](a: A): M[A] = new Suc(a) - def errorM[A](msg: String): M[A] = new Err(msg) - - def showM(m: M[Value]): String = m.show - - class Suc[A](x: A) extends M[A] { - def bind[B](k: A => M[B]): M[B] = k(x) - def show: String = "Success: " + x - } - class Err[A](msg: String) extends M[A] { - def bind[B](k: A => M[B]): M[B] = new Err(msg) - def show: String = "Error: " + msg - } - - type Name = String - - trait Term - case class Var(x: Name) extends Term - case class Con(n: Int) extends Term - case class Add(l: Term, r: Term) extends Term - case class Lam(x: Name, body: Term) extends Term - case class App(fun: Term, arg: Term) extends Term - - trait Value - case object Wrong extends Value { - override def toString() = "wrong" - } - case class Num(n: Int) extends Value { - override def toString() = n.toString() - } - case class Fun(f: Value => M[Value]) extends Value { - override def toString() = "<function>" - } - - type Environment = List[Tuple2[Name, Value]] - - def lookup(x: Name, e: Environment): M[Value] = e match { - case List() => errorM("unbound variable: " + x); - case (y, b) :: e1 => if (x == y) unitM(b) else lookup(x, e1) - } - - def add(a: Value, b: Value): M[Value] = (a, b) match { - case (Num(m), Num(n)) => unitM(Num(m + n)) - case _ => errorM("should be numbers: " + a + "," + b) - } - - def apply(a: Value, b: Value): M[Value] = a match { - case Fun(k) => k(b) - case _ => errorM("should be function: " + a) - } - - def interp(t: Term, e: Environment): M[Value] = t match { - case Var(x) => lookup(x, e) - case Con(n) => unitM(Num(n)) - case Add(l, r) => for (a <- interp(l, e); - b <- interp(r, e); - c <- add(a, b)) - yield c - case Lam(x, t) => unitM(Fun(a => interp(t, (x, a) :: e))) - case App(f, t) => for (a <- interp(f, e); - b <- interp(t, e); - c <- apply(a, b)) - yield c - } - - def test(t: Term): String = - showM(interp(t, List())) - - val term0 = App(Lam("x", Add(Var("x"), Var("x"))), Add(Con(10), Con(11))) - val term1 = App(Con(1), Con(2)) - - def main(args: Array[String]) = { - System.out.println(test(term0)) - System.out.println(test(term1)) - } -} - diff --git a/docs/examples/monads/simpleInterpreter.scala b/docs/examples/monads/simpleInterpreter.scala deleted file mode 100644 index 64636749ff..0000000000 --- a/docs/examples/monads/simpleInterpreter.scala +++ /dev/null @@ -1,75 +0,0 @@ -object simpleInterpreter { - - case class M[A](value: A) { - def bind[B](k: A => M[B]): M[B] = k(value); - def map[B](f: A => B): M[B] = bind(x => unitM(f(x))); - def flatMap[B](f: A => M[B]): M[B] = bind(f); - } - - def unitM[A](a: A): M[A] = M(a); - - def showM(m: M[Value]): String = m.value.toString(); - - type Name = String; - - trait Term; - case class Var(x: Name) extends Term; - case class Con(n: Int) extends Term; - case class Add(l: Term, r: Term) extends Term; - case class Lam(x: Name, body: Term) extends Term; - case class App(fun: Term, arg: Term) extends Term; - - trait Value; - case object Wrong extends Value { - override def toString() = "wrong" - } - case class Num(n: Int) extends Value { - override def toString() = n.toString(); - } - case class Fun(f: Value => M[Value]) extends Value { - override def toString() = "<function>" - } - - type Environment = List[Tuple2[Name, Value]]; - - def lookup(x: Name, e: Environment): M[Value] = e match { - case List() => unitM(Wrong) - case (y, b) :: e1 => if (x == y) unitM(b) else lookup(x, e1) - } - - def add(a: Value, b: Value): M[Value] = (a, b) match { - case (Num(m), Num(n)) => unitM(Num(m + n)) - case _ => unitM(Wrong) - } - - def apply(a: Value, b: Value): M[Value] = a match { - case Fun(k) => k(b) - case _ => unitM(Wrong) - } - - def interp(t: Term, e: Environment): M[Value] = t match { - case Var(x) => lookup(x, e) - case Con(n) => unitM(Num(n)) - case Add(l, r) => for (a <- interp(l, e); - b <- interp(r, e); - c <- add(a, b)) - yield c - case Lam(x, t) => unitM(Fun(a => interp(t, (x, a) :: e))) - case App(f, t) => for (a <- interp(f, e); - b <- interp(t, e); - c <- apply(a, b)) - yield c - } - - def test(t: Term): String = - showM(interp(t, List())); - - val term0 = App(Lam("x", Add(Var("x"), Var("x"))), Add(Con(10), Con(11))); - val term1 = App(Con(1), Con(2)); - - def main(args: Array[String]) = { - System.out.println(test(term0)); - System.out.println(test(term1)); - } -} - diff --git a/docs/examples/monads/stateInterpreter.scala b/docs/examples/monads/stateInterpreter.scala deleted file mode 100644 index e13e9049da..0000000000 --- a/docs/examples/monads/stateInterpreter.scala +++ /dev/null @@ -1,86 +0,0 @@ -package examples.monads; - -object stateInterpreter { - - type State = Int; - - val tickS = new M(s => ((), s + 1)); - - case class M[A](in: State => Tuple2[A, State]) { - def bind[B](k: A => M[B]) = M[B]{ s0 => - val (a, s1) = this in s0; k(a) in s1 - } - def map[B](f: A => B): M[B] = bind(x => unitM(f(x))); - def flatMap[B](f: A => M[B]): M[B] = bind(f); - } - - def unitM[A](a: A) = M[A](s => (a, s)); - - def showM(m: M[Value]): String = { - val (a, s1) = m in 0; - "Value: " + a + "; Count: " + s1 - } - - type Name = String; - - trait Term; - case class Var(x: Name) extends Term; - case class Con(n: Int) extends Term; - case class Add(l: Term, r: Term) extends Term; - case class Lam(x: Name, body: Term) extends Term; - case class App(fun: Term, arg: Term) extends Term; - - trait Value; - case object Wrong extends Value { - override def toString() = "wrong" - } - case class Num(n: Int) extends Value { - override def toString() = n.toString(); - } - case class Fun(f: Value => M[Value]) extends Value { - override def toString() = "<function>" - } - - type Environment = List[Tuple2[Name, Value]]; - - def lookup(x: Name, e: Environment): M[Value] = e match { - case List() => unitM(Wrong) - case (y, b) :: e1 => if (x == y) unitM(b) else lookup(x, e1) - } - - def add(a: Value, b: Value): M[Value] = (a, b) match { - case (Num(m), Num(n)) => for (_ <- tickS) yield Num(m + n) - case _ => unitM(Wrong) - } - - def apply(a: Value, b: Value): M[Value] = a match { - case Fun(k) => for (_ <- tickS; c <- k(b)) yield c - case _ => unitM(Wrong) - } - - def interp(t: Term, e: Environment): M[Value] = t match { - case Var(x) => lookup(x, e) - case Con(n) => unitM(Num(n)) - case Add(l, r) => for (a <- interp(l, e); - b <- interp(r, e); - c <- add(a, b)) - yield c - case Lam(x, t) => unitM(Fun(a => interp(t, (x, a) :: e))) - case App(f, t) => for (a <- interp(f, e); - b <- interp(t, e); - c <- apply(a, b)) - yield c - } - - def test(t: Term): String = - showM(interp(t, List())); - - val term0 = App(Lam("x", Add(Var("x"), Var("x"))), Add(Con(10), Con(11))); - val term1 = App(Con(1), Con(2)); - - def main(args: Array[String]) = { - System.out.println(test(term0)); - System.out.println(test(term1)); - } -} - diff --git a/docs/examples/oneplacebuffer.scala b/docs/examples/oneplacebuffer.scala deleted file mode 100644 index f7047a1c92..0000000000 --- a/docs/examples/oneplacebuffer.scala +++ /dev/null @@ -1,64 +0,0 @@ -package examples - -object oneplacebuffer { - - import scala.actors.Actor._ - import scala.concurrent.ops - - class OnePlaceBuffer { - private case class Put(x: Int) - private case object Get - - private val m = actor { - var buf: Option[Int] = None - loop { - react { - case Put(x) if buf.isEmpty => - println("put "+x); - buf = Some(x); reply() - case Get if !buf.isEmpty => - val x = buf.get - println("get "+x) - buf = None; reply(x) - } - } - } - m.start() - - def write(x: Int) { m !? Put(x) } - - def read(): Int = (m !? Get).asInstanceOf[Int] - } - - def kill(delay: Int) = new java.util.Timer().schedule( - new java.util.TimerTask { - override def run() { - println("[killed]") - sys exit 0 - } - }, - delay) // in milliseconds - - def main(args: Array[String]) { - val buf = new OnePlaceBuffer - val random = new java.util.Random() - - def producer(n: Int) { - Thread.sleep(random nextInt 1000) - buf write n - producer(n + 1) - } - - def consumer { - Thread.sleep(random nextInt 1000) - val n = buf.read() - consumer - } - - ops spawn producer(0) - ops spawn consumer - kill(10000) - } - -} - diff --git a/docs/examples/parsing/ArithmeticParser.scala b/docs/examples/parsing/ArithmeticParser.scala deleted file mode 100644 index c272fa0ba0..0000000000 --- a/docs/examples/parsing/ArithmeticParser.scala +++ /dev/null @@ -1,57 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package examples.parsing - -import scala.util.parsing.combinator.lexical.StdLexical -import scala.util.parsing.combinator.syntactical.StdTokenParsers - -/** Parse and evaluate a numeric expression as a sequence of terms, separated by + or - - * a term is a sequence of factors, separated by * or / - * a factor is a parenthesized expression or a number - * - * @author Adriaan Moors - */ -object arithmeticParser extends StdTokenParsers { - type Tokens = StdLexical ; val lexical = new StdLexical - lexical.delimiters ++= List("(", ")", "+", "-", "*", "/") - - lazy val expr = term*("+" ^^^ {(x: int, y: int) => x + y} | "-" ^^^ {(x: int, y: int) => x - y}) - lazy val term = factor*("*" ^^^ {(x: int, y: int) => x * y} | "/" ^^^ {(x: int, y: int) => x / y}) - lazy val factor: Parser[int] = "(" ~> expr <~ ")" | numericLit ^^ (_.toInt) - - def main(args: Array[String]) { - println( - if (args.length == 1) { - expr(new lexical.Scanner(args(0))) - } - else - "usage: scala examples.parsing.arithmeticParser <expr-string>" - ) - } -} - - -object arithmeticParserDesugared extends StdTokenParsers { - type Tokens = StdLexical ; val lexical = new StdLexical - lexical.delimiters ++= List("(", ")", "+", "-", "*", "/") - - lazy val expr = chainl1(term, (keyword("+").^^^{(x: int, y: int) => x + y}).|(keyword("-").^^^{(x: int, y: int) => x - y})) - lazy val term = chainl1(factor, (keyword("*").^^^{(x: int, y: int) => x * y}).|(keyword("/").^^^{(x: int, y: int) => x / y})) - lazy val factor: Parser[int] = keyword("(").~>(expr.<~(keyword(")"))).|(numericLit.^^(x => x.toInt)) - - def main(args: Array[String]) { - println( - if (args.length == 1) { - expr(new lexical.Scanner(args(0))) - } - else - "usage: scala examples.parsing.arithmeticParser <expr-string>" - ) - } -} diff --git a/docs/examples/parsing/ArithmeticParsers.scala b/docs/examples/parsing/ArithmeticParsers.scala deleted file mode 100644 index 62d7a61862..0000000000 --- a/docs/examples/parsing/ArithmeticParsers.scala +++ /dev/null @@ -1,70 +0,0 @@ -package examples.parsing - -import scala.util.parsing.combinator1.syntactical.StandardTokenParsers - -object ArithmeticParsers extends StandardTokenParsers { - lexical.delimiters ++= List("(", ")", "+", "-", "*", "/") - - def expr: Parser[Any] = term ~ rep("+" ~ term | "-" ~ term) - def term = factor ~ rep("*" ~ factor | "/" ~ factor) - def factor: Parser[Any] = "(" ~ expr ~ ")" | numericLit - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(expr)(tokens)) - } -} - -object ArithmeticParsers1 extends StandardTokenParsers { - lexical.delimiters ++= List("(", ")", "+", "-", "*", "/") - - val reduceList: Int ~ List[String ~ Int] => Int = { - case i ~ ps => (i /: ps)(reduce) - } - - def reduce(x: Int, r: String ~ Int) = (r: @unchecked) match { - case "+" ~ y => x + y - case "-" ~ y => x - y - case "*" ~ y => x * y - case "/" ~ y => x / y - } - - def expr : Parser[Int] = term ~ rep ("+" ~ term | "-" ~ term) ^^ reduceList - def term : Parser[Int] = factor ~ rep ("*" ~ factor | "/" ~ factor) ^^ reduceList - def factor: Parser[Int] = "(" ~> expr <~ ")" | numericLit ^^ (_.toInt) - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(expr)(tokens)) - } -} - -class Expr -case class BinOp(op: String, l: Expr, r: Expr) extends Expr -case class Num(n: Int) extends Expr - -object ArithmeticParsers2 extends StandardTokenParsers { - lexical.delimiters ++= List("(", ")", "+", "-", "*", "/") - - val reduceList: Expr ~ List[String ~ Expr] => Expr = { - case i ~ ps => (i /: ps)(reduce) - } - - def reduce(l: Expr, r: String ~ Expr) = BinOp(r._1, l, r._2) - def mkNum(s: String) = Num(s.toInt) - - def expr : Parser[Expr] = term ~ rep ("+" ~ term | "-" ~ term) ^^ reduceList - def term : Parser[Expr] = factor ~ rep ("*" ~ factor | "/" ~ factor) ^^ reduceList - def factor: Parser[Expr] = "(" ~> expr <~ ")" | numericLit ^^ ((s: String) => Num(s.toInt)) - - def main(args: Array[String]) { - val parse = phrase(expr) - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(parse(tokens)) - } -} - - diff --git a/docs/examples/parsing/JSON.scala b/docs/examples/parsing/JSON.scala deleted file mode 100644 index abfa242e9f..0000000000 --- a/docs/examples/parsing/JSON.scala +++ /dev/null @@ -1,44 +0,0 @@ -package examples.parsing - -import scala.util.parsing.combinator1.syntactical.StandardTokenParsers - -object JSON extends StandardTokenParsers { - lexical.delimiters += ("{", "}", "[", "]", ":", ",") - lexical.reserved += ("null", "true", "false") - - def obj : Parser[Any] = "{" ~ repsep(member, ",") ~ "}" - def arr : Parser[Any] = "[" ~ repsep(value, ",") ~ "]" - def member: Parser[Any] = ident ~ ":" ~ value - def value : Parser[Any] = ident | numericLit | obj | arr | - "null" | "true" | "false" - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(value)(tokens)) - } -} -object JSON1 extends StandardTokenParsers { - lexical.delimiters += ("{", "}", "[", "]", ":", ",") - lexical.reserved += ("null", "true", "false") - - def obj: Parser[Map[String, Any]] = - "{" ~> repsep(member, ",") <~ "}" ^^ (Map() ++ _) - - def arr: Parser[List[Any]] = - "[" ~> repsep(value, ",") <~ "]" - - def member: Parser[(String, Any)] = - ident ~ ":" ~ value ^^ { case name ~ ":" ~ value => (name -> value) } - - def value: Parser[Any] = - ident | numericLit ^^ (_.toInt) | obj | arr | - "null" ^^^ null | "true" ^^^ true | "false" ^^^ false - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(value)(tokens)) - } -} - diff --git a/docs/examples/parsing/ListParser.scala b/docs/examples/parsing/ListParser.scala deleted file mode 100644 index 59fc292c1d..0000000000 --- a/docs/examples/parsing/ListParser.scala +++ /dev/null @@ -1,33 +0,0 @@ -package examples.parsing - -import scala.util.parsing.combinator.{Parsers, ImplicitConversions, ~, mkTilde} -import scala.util.parsing.input.CharArrayReader - -object listParser { - abstract class Tree - case class Id(s: String) extends Tree - case class Num(n: Int) extends Tree - case class Lst(elems: List[Tree]) extends Tree - - import Character.{isLetter, isLetterOrDigit, isDigit} - def mkString(cs: List[Any]) = cs.mkString("") - - class ListParsers extends Parsers { - type Elem = Char - - lazy val ident = rep1(elem("letter", isLetter), elem("letter or digit", isLetterOrDigit)) ^^ {cs => Id(mkString(cs))} - lazy val number = chainl1(elem("digit", isDigit) ^^ (_ - '0'), success{(accum: Int, d: Int) => accum * 10 + d}) ^^ Num - lazy val list = '(' ~> repsep(expr, ',') <~ ')' ^^ Lst - lazy val expr: Parser[Tree] = list | ident | number - } - - def main(args: Array[String]) { - println( - if (args.length == 1) { - (new ListParsers).expr(new CharArrayReader(args(0).toCharArray())) - } - else - "usage: scala examples.parsing.listParser <list-string>" - ) - } -} diff --git a/docs/examples/parsing/ListParsers.scala b/docs/examples/parsing/ListParsers.scala deleted file mode 100644 index b449c4a641..0000000000 --- a/docs/examples/parsing/ListParsers.scala +++ /dev/null @@ -1,30 +0,0 @@ -package examples.parsing - -import scala.util.parsing.combinator1.syntactical.StandardTokenParsers - -object ListParsers extends StandardTokenParsers { - lexical.delimiters ++= List("(", ")", ",") - - def expr: Parser[Any] = "(" ~ exprs ~ ")" | ident | numericLit - def exprs: Parser[Any] = expr ~ rep ("," ~ expr) - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(expr)(tokens)) - } -} - -object ListParsers1 extends StandardTokenParsers { - lexical.delimiters ++= List("(", ")", ",") - - def expr: Parser[Any] = "(" ~> exprs <~ ")" | ident | numericLit - - def exprs: Parser[List[Any]] = expr ~ rep ("," ~> expr) ^^ { case x ~ y => x :: y } - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(expr)(tokens)) - } -} diff --git a/docs/examples/parsing/MiniML.scala b/docs/examples/parsing/MiniML.scala deleted file mode 100644 index f7f7172e8d..0000000000 --- a/docs/examples/parsing/MiniML.scala +++ /dev/null @@ -1,52 +0,0 @@ -package examples.parsing - -import scala.util.parsing.combinator1.syntactical.StandardTokenParsers -import scala.util.parsing.combinator1.syntactical.StandardTokenParsers - -object MiniML extends StandardTokenParsers { - lexical.delimiters += ("(", ")", ".", "=") - lexical.reserved += ("lambda", "let", "in") - - def expr: Parser[Any] = ( - "let" ~ ident ~ "=" ~ expr ~ "in" ~ expr - | "lambda" ~ ident ~ "." ~ expr - | simpleExpr ~ rep(expr) - ) - def simpleExpr: Parser[Any] = ( - ident - | "(" ~ expr ~ ")" - ) - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(expr)(tokens)) - } -} - -class Expr -case class Let(x: String, expr: Expr, body: Expr) extends Expr -case class Lambda(x: String, expr: Expr) extends Expr -case class Apply(fun: Expr, arg: Expr) extends Expr -case class Var(x: String) extends Expr - -object MiniML1 extends StandardTokenParsers { - lexical.delimiters += ("(", ")", ".", "=") - lexical.reserved += ("lambda", "let", "in") - - def expr: Parser[Expr] = ( - "let" ~ ident ~ "=" ~ expr ~ "in" ~ expr ^^ { case "let" ~ x ~ "=" ~ e ~ "in" ~ b => Let(x, e, b) } - | "lambda" ~ ident ~ "." ~ expr ^^ { case "lambda" ~ x ~ "." ~ e => Lambda(x, e) } - | simpleExpr ~ rep(expr) ^^ { case f ~ as => (f /: as) (Apply) } - ) - def simpleExpr: Parser[Expr] = ( - ident ^^ { Var } - | "(" ~> expr <~ ")" - ) - - def main(args: Array[String]) { - val tokens = new lexical.Scanner(args(0)) - println(args(0)) - println(phrase(expr)(tokens)) - } -} diff --git a/docs/examples/parsing/lambda/Main.scala b/docs/examples/parsing/lambda/Main.scala deleted file mode 100644 index 165e82b670..0000000000 --- a/docs/examples/parsing/lambda/Main.scala +++ /dev/null @@ -1,34 +0,0 @@ -package examples.parsing.lambda - -import scala.util.parsing.combinator.Parsers -import scala.util.parsing.input.StreamReader - -import java.io.File -import java.io.FileInputStream -import java.io.InputStreamReader - -/** - * Parser for an untyped lambda calculus - * - * Usage: scala examples.parsing.lambda.Main <file> - * - * (example files: see test/ *.kwi) - * - * @author Miles Sabin (adapted slightly by Adriaan Moors) - */ -object Main extends Application with TestParser -{ - override def main(args: Array[String]) = - { - val in = StreamReader(new InputStreamReader(new FileInputStream(new File(args(0))), "ISO-8859-1")) - parse(in) match - { - case Success(term, _) => - { - Console.println("Term: \n"+term) - } - case Failure(msg, remainder) => Console.println("Failure: "+msg+"\n"+"Remainder: \n"+remainder.pos.longString) - case Error(msg, remainder) => Console.println("Error: "+msg+"\n"+"Remainder: \n"+remainder.pos.longString) - } - } -} diff --git a/docs/examples/parsing/lambda/TestParser.scala b/docs/examples/parsing/lambda/TestParser.scala deleted file mode 100644 index d26589da1b..0000000000 --- a/docs/examples/parsing/lambda/TestParser.scala +++ /dev/null @@ -1,68 +0,0 @@ -package examples.parsing.lambda - -import scala.util.parsing.input.Reader -import scala.util.parsing.combinator.lexical.StdLexical -import scala.util.parsing.combinator.syntactical.StdTokenParsers -import scala.util.parsing.combinator.ImplicitConversions - -/** - * Parser for an untyped lambda calculus - * - * @author Miles Sabin (adapted slightly by Adriaan Moors) - */ -trait TestParser extends StdTokenParsers with ImplicitConversions with TestSyntax -{ - type Tokens = StdLexical - val lexical = new StdLexical - lexical.reserved ++= List("unit", "let", "in", "if", "then", "else") - lexical.delimiters ++= List("=>", "->", "==", "(", ")", "=", "\\", "+", "-", "*", "/") - - - def name : Parser[Name] = ident ^^ Name - - // meaning of the arguments to the closure during subsequent iterations - // (...(expr2 op1 expr1) ... op1 expr1) - // ^a^^^ ^o^ ^b^^^ - // ^^^^^^^a^^^^^^^ ^o^ ^^b^^ - def expr1 : Parser[Term] = - chainl1(expr2, expr1, op1 ^^ {o => (a: Term, b: Term) => App(App(o, a), b)}) - - def expr2 : Parser[Term] = - chainl1(expr3, expr2, op2 ^^ {o => (a: Term, b: Term) => App(App(o, a), b)}) - - def expr3 : Parser[Term] = - chainl1(expr4, expr3, op3 ^^ {o => (a: Term, b: Term) => App(App(o, a), b)}) - - def expr4 : Parser[Term] = - ( "\\" ~> lambdas - | ("let" ~> name) ~ ("=" ~> expr1) ~ ("in" ~> expr1) ^^ flatten3(Let) - | ("if" ~> expr1) ~ ("then" ~> expr1) ~ ("else" ~> expr1) ^^ flatten3(If) - | chainl1(aexpr, success(App(_: Term, _: Term))) - ) - - def lambdas : Parser[Term] = - name ~ ("->" ~> expr1 | lambdas) ^^ flatten2(Lam) - - def aexpr : Parser[Term] = - ( numericLit ^^ (_.toInt) ^^ Lit - | name ^^ Ref - | "unit" ^^^ Unit() - | "(" ~> expr1 <~ ")" - ) - - def op1 : Parser[Term] = - "==" ^^^ Ref(Name("==")) - - def op2 : Parser[Term] = - ( "+" ^^^ Ref(Name("+")) - | "-" ^^^ Ref(Name("-")) - ) - - def op3 : Parser[Term] = - ( "*" ^^^ Ref(Name("*")) - | "/" ^^^ Ref(Name("/")) - ) - - def parse(r: Reader[char]) : ParseResult[Term] = - phrase(expr1)(new lexical.Scanner(r)) -} diff --git a/docs/examples/parsing/lambda/TestSyntax.scala b/docs/examples/parsing/lambda/TestSyntax.scala deleted file mode 100644 index 7edca6ccdc..0000000000 --- a/docs/examples/parsing/lambda/TestSyntax.scala +++ /dev/null @@ -1,86 +0,0 @@ -package examples.parsing.lambda - -/** - * Parser for an untyped lambda calculus: abstract syntax tree - * - * @author Miles Sabin (adapted slightly by Adriaan Moors) - */ -trait TestSyntax -{ - trait Term - - case class Unit extends Term - { - override def toString = "unit" - } - - case class Lit(n: int) extends Term - { - override def toString = n.toString - } - - case class Bool(b: boolean) extends Term - { - override def toString = b.toString - } - - case class Name(name: String) extends Term - { - override def toString = name - } - - case class Ref(n: Name) extends Term - { - def value = n - } - - case class Lam(n: Name, l: Term) extends Term - { - override def toString = "(\\ "+n+" -> "+l+")" - } - - case class App(t1: Term, t2: Term) extends Term - { - override def toString = "("+t1+" "+t2+")" - } - - case class Let(n: Name, t1: Term, t2: Term) extends Term - { - override def toString = "let "+n+" = "+t1+" in "+t2 - } - - case class If(c: Term, t1: Term, t2: Term) extends Term - { - override def toString = "if "+c+" then "+t1+" else "+t2 - } - - trait PrimTerm extends Term - { - def apply(n: Lit) : Term - } - - case class PrimPlus extends PrimTerm - { - def apply(x: Lit) = new PrimTerm { def apply(y: Lit) = Lit(x.n+y.n) } - } - - case class PrimMinus extends PrimTerm - { - def apply(x: Lit) = new PrimTerm { def apply(y: Lit) = Lit(x.n-y.n) } - } - - case class PrimMultiply extends PrimTerm - { - def apply(x: Lit) = new PrimTerm { def apply(y: Lit) = Lit(x.n*y.n) } - } - - case class PrimDivide extends PrimTerm - { - def apply(x: Lit) = new PrimTerm { def apply(y: Lit) = Lit(x.n/y.n) } - } - - case class PrimEquals extends PrimTerm - { - def apply(x: Lit) = new PrimTerm { def apply(y: Lit) = Bool(x.n == y.n) } - } -} diff --git a/docs/examples/parsing/lambda/test/test-01.kwi b/docs/examples/parsing/lambda/test/test-01.kwi deleted file mode 100644 index 9833d10673..0000000000 --- a/docs/examples/parsing/lambda/test/test-01.kwi +++ /dev/null @@ -1 +0,0 @@ -let x = 23 in (\y z -> x+y+z) 1 2 diff --git a/docs/examples/parsing/lambda/test/test-02.kwi b/docs/examples/parsing/lambda/test/test-02.kwi deleted file mode 100644 index 11198c6fc9..0000000000 --- a/docs/examples/parsing/lambda/test/test-02.kwi +++ /dev/null @@ -1 +0,0 @@ -let f = (\x y -> x*y) in f 2 3 diff --git a/docs/examples/parsing/lambda/test/test-03.kwi b/docs/examples/parsing/lambda/test/test-03.kwi deleted file mode 100644 index d4515d7297..0000000000 --- a/docs/examples/parsing/lambda/test/test-03.kwi +++ /dev/null @@ -1 +0,0 @@ -let f = (\x y -> x*y) in f (f 1 2) 3 diff --git a/docs/examples/parsing/lambda/test/test-04.kwi b/docs/examples/parsing/lambda/test/test-04.kwi deleted file mode 100644 index e54c45457a..0000000000 --- a/docs/examples/parsing/lambda/test/test-04.kwi +++ /dev/null @@ -1 +0,0 @@ -let fact = \x -> if x == 0 then 1 else x*(fact (x-1)) in unit diff --git a/docs/examples/parsing/lambda/test/test-05.kwi b/docs/examples/parsing/lambda/test/test-05.kwi deleted file mode 100644 index 0b95d67846..0000000000 --- a/docs/examples/parsing/lambda/test/test-05.kwi +++ /dev/null @@ -1 +0,0 @@ -let fact = \x -> if x == 0 then 1 else x*(fact (x-1)) in fact 6 diff --git a/docs/examples/parsing/lambda/test/test-06.kwi b/docs/examples/parsing/lambda/test/test-06.kwi deleted file mode 100644 index 47723dc998..0000000000 --- a/docs/examples/parsing/lambda/test/test-06.kwi +++ /dev/null @@ -1 +0,0 @@ -2*3+4*5 == 26 diff --git a/docs/examples/parsing/lambda/test/test-07.kwi b/docs/examples/parsing/lambda/test/test-07.kwi deleted file mode 100644 index 14fba0d66a..0000000000 --- a/docs/examples/parsing/lambda/test/test-07.kwi +++ /dev/null @@ -1 +0,0 @@ -let fix = \f -> f(fix f) in unit diff --git a/docs/examples/parsing/lambda/test/test-08.kwi b/docs/examples/parsing/lambda/test/test-08.kwi deleted file mode 100644 index 7166d154f0..0000000000 --- a/docs/examples/parsing/lambda/test/test-08.kwi +++ /dev/null @@ -1 +0,0 @@ -let fix = (\f -> f(fix f)) in (fix (\g n -> if n == 0 then 1 else n*(g(n-1)))) 5 diff --git a/docs/examples/patterns.scala b/docs/examples/patterns.scala deleted file mode 100644 index d082fcc3de..0000000000 --- a/docs/examples/patterns.scala +++ /dev/null @@ -1,36 +0,0 @@ -package examples - -object patterns { - - trait Tree - case class Branch(left: Tree, right: Tree) extends Tree - case class Leaf(x: Int) extends Tree - - val tree1 = Branch(Branch(Leaf(1), Leaf(2)), Branch(Leaf(3), Leaf(4))) - - def sumLeaves(t: Tree): Int = t match { - case Branch(l, r) => sumLeaves(l) + sumLeaves(r) - case Leaf(x) => x - } - - def find[a,b](it: Iterator[Tuple2[a, b]], x: a): Option[b] = { - var result: Option[b] = None - var found = false - while (it.hasNext && !found) { - val (x1, y) = it.next - if (x == x1) { found = true; result = Some(y) } - } - result - } - - def printFinds[a](xs: List[Tuple2[a, String]], x: a) = - find(xs.iterator, x) match { - case Some(y) => System.out.println(y) - case None => System.out.println("no match") - } - - def main(args: Array[String]) { - println("sum of leafs=" + sumLeaves(tree1)) - printFinds(List((3, "three"), (4, "four")), 4) - } -} diff --git a/docs/examples/pilib/elasticBuffer.scala b/docs/examples/pilib/elasticBuffer.scala deleted file mode 100644 index c173735dbb..0000000000 --- a/docs/examples/pilib/elasticBuffer.scala +++ /dev/null @@ -1,77 +0,0 @@ -package examples.pilib - -object elasticBuffer { - - import scala.concurrent.pilib._ - - /** - * Recursive type for channels that carry a "String" channel and - * an object of the type we define. - */ - class MetaChan extends Chan[Tuple2[Chan[String], MetaChan]] - - def Buffer(put: Chan[String], get: Chan[String]): Unit = { - - /** - * An empty buffer cell, ready to pass on (o,r) to the left. - */ - def Bl(i:Chan[String], l: MetaChan, - o: Chan[String], r: MetaChan): unit = - choice ( - l((o,r)) * (System.out.println("Removed one cell.")), - i * (inp => Cl(i, l, o, r, inp)) - ) - - /** - * A buffer cell containing a value, ready to receive (o,r) from the right. - */ - def Cl(i: Chan[String], l: MetaChan, - o: Chan[String], r: MetaChan, content: String): Unit = - choice ( - o(content) * (Bl(i,l,o,r)), - i * (inp => Dl(i,l,o,r,content, inp)), - r * ( { case (newo, newr) => Cl(i,l,newo,newr,content) }) - ) - - /** - * Two joined buffer cells, of type Cl - */ - def Dl(i: Chan[String], l: MetaChan, - o: Chan[String], r: MetaChan, - content: String, inp: String): Unit = { - val newlr = new MetaChan - val newio = new Chan[String] - spawn < Cl(i, l, newio, newlr, inp) | Cl(newio, newlr, o, r, content) > - } - - // l and r channels for the leftmost and rightmost cell, respectively. - val unused1 = new MetaChan - val unused2 = new MetaChan - - Bl(put, unused1, get, unused2) - } - - val random = new java.util.Random() - - def Producer(n: int, put: Chan[String]): Unit = { - Thread.sleep(1 + random.nextInt(1000)) - val msg = "object " + n - put.write(msg) - System.out.println("Producer gave " + msg) - Producer(n + 1, put) - } - - def Consumer(get: Chan[String]): Unit = { - Thread.sleep(1 + random.nextInt(1000)) - val msg = get.read - System.out.println("Consumer took " + msg) - Consumer(get) - } - - def main(args: Array[String]): Unit = { - val put = new Chan[String] - val get = new Chan[String] - spawn < Producer(0, put) | Consumer(get) | Buffer(put, get) > - } - -} diff --git a/docs/examples/pilib/handover.scala b/docs/examples/pilib/handover.scala deleted file mode 100644 index 4e9a5670a0..0000000000 --- a/docs/examples/pilib/handover.scala +++ /dev/null @@ -1,186 +0,0 @@ -package examples.pilib - -/** - * Handover example with recursive types for channels. - */ -object handoverRecursive { - - import concurrent.pilib._ - - val random = new java.util.Random() - - /** - * Recursive type for channels that carry a channel "unit" and - * an object of the type we define. - */ - class Switch extends Chan[Tuple2[Chan[unit], Switch]] - - /** - * Car. - */ - def Car(talk: Chan[unit], switch: Switch): unit = - choice ( - switch * ({ case (t,s) => Car(t, s) }), - talk(()) * ( { - Thread.sleep(1 + random.nextInt(1000)); - System.out.println("Car emitted a message."); - Car(talk, switch) - }) - ); - - /** - * Control center. - */ - def Control(talk1: Chan[unit], switch1: Switch, - gain1: Switch, lose1: Switch, - talk2: Chan[unit], switch2: Switch, - gain2: Switch, lose2: Switch): unit - = { - def Control1: unit= { - Thread.sleep(1 + random.nextInt(1000)); - lose1.write((talk2, switch2)); - gain2.write((talk2, switch2)); - Control2 - } - def Control2: unit = { - Thread.sleep(1 + random.nextInt(1000)); - lose2.write((talk1, switch1)); - gain1.write((talk1, switch1)); - Control1 - } - Control1 - } - - /** - * Active transmitter. - */ - def ActiveTransmitter(id: String, talk: Chan[unit], switch: Switch, - gain: Switch, lose: Switch): unit - = - choice ( - talk * (x => { - System.out.println(id + " received a message.") - ActiveTransmitter(id, talk, switch, gain, lose) - }), - lose * ({ case (t, s) => { - switch.write((t, s)) - IdleTransmitter(id, gain, lose) - }}) - ); - - /** - * Idle transmitter. - */ - def IdleTransmitter(id: String, gain: Switch, lose: Switch): unit = { - val (t, s) = gain.read; - ActiveTransmitter(id, t, s, gain, lose) - } - - def main(args: Array[String]): unit = { - val talk1 = new Chan[unit] - val switch1 = new Switch - val gain1 = new Switch - val lose1 = new Switch - val talk2 = new Chan[unit] - val switch2 = new Switch - val gain2 = new Switch - val lose2 = new Switch - spawn < - Car(talk1, switch1) | - ActiveTransmitter("Transmitter 1", talk1, switch1, gain1, lose1) | - IdleTransmitter("Transmitter 2", gain2, lose2) | - Control(talk1, switch1, gain1, lose1, talk2, switch2, gain2, lose2) > - } -} - -/** -* Handover example with type casts. -*/ -object handoverCast { - - import concurrent.pilib._; - - val random = new java.util.Random(); - - /** - * Car. - */ - def Car(talk: Chan[Any], switch: Chan[Any]): unit = - choice ( - switch * (o => { - val (t,s) = o.asInstanceOf[Tuple2[Chan[Any],Chan[Any]]]; - Car(t, s) - }), - talk(()) * ( { - Thread.sleep(1 + random.nextInt(1000)); - System.out.println("Car emitted a message."); - Car(talk, switch) - }) - ); - - /** - * Control center. - */ - def Control(talk1: Chan[Any], switch1: Chan[Any], - gain1: Chan[Any], lose1: Chan[Any], - talk2: Chan[Any], switch2: Chan[Any], - gain2: Chan[Any], lose2: Chan[Any]): unit - = { - def Control1: unit = { - Thread.sleep(1 + random.nextInt(1000)); - lose1.write((talk2, switch2)); - gain2.write((talk2, switch2)); - Control2 - } - def Control2: unit = { - Thread.sleep(1 + random.nextInt(1000)); - lose2.write((talk1, switch1)); - gain1.write((talk1, switch1)); - Control1 - } - Control1 - } - - /** - * Active transmitter. - */ - def ActiveTransmitter(id: String, talk: Chan[Any], switch: Chan[Any], - gain: Chan[Any], lose: Chan[Any]): unit - = - choice ( - talk * (x => { - System.out.println(id + " received a message.") - ActiveTransmitter(id, talk, switch, gain, lose) - }), - lose * (o => { - val (t, s) = o.asInstanceOf[Tuple2[Chan[Any],Chan[Any]]] - switch.write((t, s)) - IdleTransmitter(id, gain, lose) - }) - ) - - /** - * Idle transmitter. - */ - def IdleTransmitter(id: String, gain: Chan[Any], lose: Chan[Any]): unit = { - val (t, s) = gain.read.asInstanceOf[Tuple2[Chan[Any],Chan[Any]]] - ActiveTransmitter(id, t, s, gain, lose) - } - - def main(args: Array[String]): unit = { - val talk1 = new Chan[Any] - val switch1 = new Chan[Any] - val gain1 = new Chan[Any] - val lose1 = new Chan[Any] - val talk2 = new Chan[Any] - val switch2 = new Chan[Any] - val gain2 = new Chan[Any] - val lose2 = new Chan[Any] - spawn < - Car(talk1, switch1) | - ActiveTransmitter("Transmitter 1", talk1, switch1, gain1, lose1) | - IdleTransmitter("Transmitter 2", gain2, lose2) | - Control(talk1, switch1, gain1, lose1, talk2, switch2, gain2, lose2) > - } - -} diff --git a/docs/examples/pilib/mobilePhoneProtocol.scala b/docs/examples/pilib/mobilePhoneProtocol.scala deleted file mode 100644 index e8c0ac1dc4..0000000000 --- a/docs/examples/pilib/mobilePhoneProtocol.scala +++ /dev/null @@ -1,172 +0,0 @@ -package examples.pilib - -/** -* Mobile phone protocol. -* Equivalent to a three-place buffer. -* @see Bjoern Victor "A verification tool for the polyadic pi-calculus". -*/ -object mobilePhoneProtocol { - - import concurrent.pilib._ - - val random = new java.util.Random() - - // Internal messages exchanged by the protocol. - trait Message - - // Predefined messages used by the protocol. - case class Data() extends Message; - case class HoCmd() extends Message; // handover command - case class HoAcc() extends Message; // handover access - case class HoCom() extends Message; // handover complete - case class HoFail() extends Message; // handover fail - case class ChRel() extends Message; // release - case class Voice(s: String) extends Message; // voice - case class Channel(n: Chan[Message]) extends Message; // channel - - def MobileSystem(in: Chan[String], out: Chan[String]): unit = { - - def CC(fa: Chan[Message], fp: Chan[Message], l: Chan[Channel]): unit = - choice ( - in * (v => { fa.write(Data()); fa.write(Voice(v)); CC(fa, fp, l) }) - , - l * (m_new => { - fa.write(HoCmd()); - fa.write(m_new); - choice ( - fp * ({ case HoCom() => { - System.out.println("Mobile has moved from one cell to another"); - fa.write(ChRel()); - val Channel(m_old) = fa.read; - l.write(Channel(m_old)); - CC(fp, fa, l) - }}) - , - fa * ({ case HoFail() => { - System.out.println("Mobile has failed to move from one cell to another"); - l.write(m_new); - CC(fa, fp, l) - }}) - ) - }) - ); - - /* - * Continuously orders the MSC to switch the MS to the non-used BS. - */ - def HC(l: Chan[Channel], m: Chan[Message]): unit = { - Thread.sleep(1 + random.nextInt(1000)); - l.write(Channel(m)); - val Channel(m_new) = l.read; - HC(l, m_new) - } - - /** - * Mobile switching center. - */ - def MSC(fa: Chan[Message], fp: Chan[Message], m: Chan[Message]): unit = { - val l = new Chan[Channel]; - spawn < HC(l, m) | CC(fa, fp, l) > - } - - /** - * Active base station. - */ - def BSa(f: Chan[Message], m: Chan[Message]): unit = - (f.read) match { - case Data() => { - val v = f.read; - m.write(Data()); - m.write(v); - BSa(f, m) - } - case HoCmd() => { - val v = f.read; - m.write(HoCmd()); - m.write(v); - choice ( - f * ({ case ChRel() => { - f.write(Channel(m)); - BSp(f, m) - }}) - , - m * ({ case HoFail() => { - f.write(HoFail()); - BSa(f, m) - }}) - ) - } - }; - - /** - * Passive base station. - */ - def BSp(f: Chan[Message], m: Chan[Message]): unit = { - val HoAcc = m.read - f.write(HoCom()) - BSa(f, m) - } - - /** - * Mobile station. - */ - def MS(m: Chan[Message]): unit = - (m.read) match { - case Data() => { - val Voice(v) = m.read; - out.write(v); - MS(m) - } - case HoCmd() => - (m.read) match { - case Channel(m_new) => { - if (random.nextInt(1) == 0) - choice ( m_new(HoAcc()) * (MS(m_new)) ); - else - choice ( m(HoFail()) * (MS(m)) ); - } - } - }; - - def P(fa: Chan[Message], fp: Chan[Message]): unit = { - val m = new Chan[Message]; - spawn < MSC(fa, fp, m) | BSp(fp, m) > - } - - def Q(fa: Chan[Message]): unit = { - val m = new Chan[Message]; - spawn < BSa(fa, m) | MS(m) > - } - - val fa = new Chan[Message]; - val fp = new Chan[Message]; - spawn < Q(fa) | P(fa, fp) >; - } - - //***************** Entry function ******************// - - def main(args: Array[String]): unit = { - - def Producer(n: Int, put: Chan[String]): unit = { - Thread.sleep(1 + random.nextInt(1000)); - val msg = "object " + n; - put.write(msg); - System.out.println("Producer gave " + msg); - Producer(n + 1, put) - } - - def Consumer(get: Chan[String]): unit = { - Thread.sleep(1 + random.nextInt(1000)); - val msg = get.read; - System.out.println("Consumer took " + msg); - Consumer(get) - } - - val put = new Chan[String]; - val get = new Chan[String]; - spawn < Producer(0, put) | Consumer(get) | MobileSystem(put, get) > - } - -} - - diff --git a/docs/examples/pilib/piNat.scala b/docs/examples/pilib/piNat.scala deleted file mode 100644 index c6d9bdaf5c..0000000000 --- a/docs/examples/pilib/piNat.scala +++ /dev/null @@ -1,89 +0,0 @@ -package examples.pilib - -import scala.concurrent.pilib._ - -/** Church encoding of naturals in the Pi-calculus */ -object piNat extends Application { - - /** Locations of Pi-calculus natural */ - class NatChan extends Chan[Tuple3[Chan[Unit], Chan[NatChan], Chan[NatChan]]] - - /** Zero */ - def Z(l: NatChan): Unit = choice ( - l * { case (z, sd, d) => z.write(()) } - ) - - /** Successor of Double */ - def SD(n: NatChan, l: NatChan): Unit = choice ( - l * { case (z, sd, d) => sd.write(n) } - ) - - /** Double */ - def D(n: NatChan, l: NatChan): Unit = choice ( - l * { case (z, sd, d) => d.write(n) } - ) - - /** Make "l" a location representing the natural "n" */ - def make(n: Int, l: NatChan): Unit = - if (n == 0) Z(l) - else if (n % 2 == 0) { val l1 = new NatChan; spawn < D(l1, l) >; make(n/2, l1) } - else { val l1 = new NatChan; spawn < SD(l1, l) >; make(n/2, l1) } - - /** Consume the natural "m" and put it successor at location "n" */ - def Succ(m: NatChan, n: NatChan) { - val z = new Chan[Unit] - val sd = new Chan[NatChan] - val d = new Chan[NatChan] - spawn < m.write((z, sd, d)) >; - choice ( - z * { x => make(1, n) }, - sd * { m1 => { val n1 = new NatChan; spawn < D(n1, n) >; Succ(m1, n1) } }, - d * { m1 => SD(m1, n) } - ) - } - - /** Consume the natural "l" and put two copies at locations "m" and "n" */ - def Copy(l: NatChan, m: NatChan, n: NatChan) { - val z = new Chan[Unit] - val sd = new Chan[NatChan] - val d = new Chan[NatChan] - spawn < l.write((z, sd, d)) >; - choice ( - z * { x => spawn < Z(m) >; Z(n) }, - sd * { l1 => { val m1 = new NatChan; val n1 = new NatChan; - spawn < SD(m1, m) | SD(n1, n) >; - Copy(l1, m1, n1) } }, - d * { l1 => { val m1 = new NatChan; val n1 = new NatChan; - spawn < D(m1, m) | D(n1, n) >; - Copy(l1, m1, n1) } } - ) - } - - /** Consume the natural at location "n" and return its value */ - def value(n: NatChan): Int = { - val z = new Chan[Unit] - val sd = new Chan[NatChan] - val d = new Chan[NatChan] - spawn < n.write((z, sd, d)) >; - choice ( - z * { x => 0 }, - sd * { n1 => 2 * value(n1) + 1 }, - d * { n1 => 2 * value(n1) } - ) - } - - // Test - val i = 42 - val l = new NatChan - val l1 = new NatChan - val l2 = new NatChan - val l3 = new NatChan - - spawn < - make(i, l) | - Copy(l, l1, l2) | - Succ(l2, l3) | - println("" + i + " = " + value(l1)) | - println("succ " + i + " = " + value(l3)) > - -} diff --git a/docs/examples/pilib/rwlock.scala b/docs/examples/pilib/rwlock.scala deleted file mode 100644 index bb1c26bdf2..0000000000 --- a/docs/examples/pilib/rwlock.scala +++ /dev/null @@ -1,329 +0,0 @@ -package examples.pilib - -/** -* From Pi to Scala: Semaphores, monitors, read/write locks. -* Readers/writers locks. -*/ -object rwlock { - - import scala.concurrent.pilib._ - - class Signal extends Chan[unit] { - def send = write(()) - def receive = read - } - - class CountLock { - private val busy = new Signal - def get = busy.send - def release = busy.receive - spawn < release > - } - - /** A binary semaphore - */ - class Lock { - private val busy = new Signal; - private val free = new Signal; - def get = busy.send; - def release = free.send; - spawn < (while (true) { - choice ( - busy * (x => free.receive), - free * (x => ()) - ) - }) > - } - - /** A monitor a la Java - */ - class JavaMonitor { - - private val lock = new Lock - - private var waiting: List[Signal] = Nil - - def Wait = { - val s = new Signal - waiting = s :: waiting - lock.release - s.receive - lock.get - } - - def Notify = - if (!waiting.isEmpty) { - waiting.head.send - waiting = waiting.tail - } - - def NotifyAll = - while (!waiting.isEmpty) { - waiting.head.send - waiting = waiting.tail - } - - def await(cond: => boolean): unit = - while (false == cond) (Wait) - } - - /* - class Buffer[a](size: Int) extends JavaMonitor with { - var in = 0, out = 0, n = 0; - val elems = new Array[a](size); - def put(x: a) = synchronized { - await(n < size); - elems(out) = x; - out = (out + 1) % size; - } - def get: a = synchronized { - await(n > 0); - val x = elems(in); - in = (in + 1) % size; - x - } - } - */ - - /** A readers/writers lock. */ - trait ReadWriteLock { - def startRead: unit - def startWrite: unit - def endRead: unit - def endWrite: unit - } - - /** - * A readers/writers lock, using monitor abstractions. - */ - class ReadWriteLock1 extends JavaMonitor with ReadWriteLock { - - private var nactive: int = 0 - private var nwriters: int = 0 - - def status = - System.out.println(nactive + " active, " + nwriters + " writers"); - - def startRead = synchronized { - await(nwriters == 0) - nactive = nactive + 1 - status - } - - def startWrite = synchronized { - nwriters = nwriters + 1 - await(nactive == 0) - nactive = 1 - status - } - - def endRead = synchronized { - nactive = nactive - 1 - if (nactive == 0) NotifyAll - status - } - - def endWrite = synchronized { - nwriters = nwriters - 1 - nactive = 0 - NotifyAll - status - } - } - - /** A readers/writers lock, using semaphores - */ - class ReadWriteLock2 extends ReadWriteLock { - - private var rc: int = 0 // reading readers - private var wc: int = 0 // writing writers - private var rwc: int = 0 // waiting readers - private var wwc: int = 0 // waiting writers - private val mutex = new Lock - private val rsem = new Lock - private val wsem = new Lock - - def startRead = { - mutex.get; - if (wwc > 0 || wc > 0) { - rwc = rwc + 1; - mutex.release; - rsem.get; - rwc = rwc - 1 - } - rc = rc + 1; - if (rwc > 0) rsem.release; - mutex.release - } - - def startWrite = { - mutex.get; - if (rc > 0 || wc > 0) { - wwc = wwc + 1; - mutex.release; - wsem.get; - wwc = wwc - 1 - } - wc = wc + 1; - mutex.release - } - - def endRead = { - mutex.get; - rc = rc - 1; - if (rc == 0 && wwc > 0) wsem.release; - mutex.release - } - - def endWrite = { - mutex.get; - wc = wc - 1; - if (rwc > 0) - rsem.release - else if (wwc > 0) wsem.release; - mutex.release - } - } - - /** A readers/writers lock, using channels, without priortities - */ - class ReadWriteLock3 extends ReadWriteLock { - - private val sr = new Signal - private val er = new Signal - private val sw = new Signal - private val ew = new Signal - - def startRead = sr.send - def startWrite = sw.send - def endRead = er.send - def endWrite = ew.send - - private def rwlock: unit = choice ( - sr * (x => reading(1)), - sw * (x => { ew.receive; rwlock }) - ) - - private def reading(n: int): unit = choice ( - sr * (x => reading(n+1)), - er * (x => if (n == 1) rwlock else reading(n-1)) - ) - - spawn < rwlock > - } - - /** Same, with sequencing - */ - class ReadWriteLock4 extends ReadWriteLock { - - private val rwlock = new ReadWriteLock3 - - private val sr = new Signal - private val ww = new Signal - private val sw = new Signal - - def startRead = sr.send - def startWrite = { ww.send; sw.send } - def endRead = rwlock.endRead - def endWrite = rwlock.endWrite - - private def queue: unit = choice ( - sr * (x => { rwlock.startRead ; queue }), - ww * (x => { rwlock.startWrite; sw.receive; queue }) - ) - - spawn < queue >; - } - - /** Readwritelock where writers always have priority over readers - */ - class ReadWriteLock5 extends ReadWriteLock { - - private val sr = new Signal - private val er = new Signal - private val ww = new Signal - private val sw = new Signal - private val ew = new Signal - - def startRead = sr.send - def startWrite = { ww.send; sw.send } - def endRead = er.send - def endWrite = ew.send - - private def Reading(nr: int, nw: int): unit = - if (nr == 0 && nw == 0) - choice ( - sr * (x => Reading(1, 0)), - ww * (x => Reading(0, 1)) - ) - else if (nr == 0 && nw != 0) { - sw.receive; - Writing(nw); - } - else if (nr != 0 && nw == 0) - choice ( - sr * (x => Reading(nr + 1, 0)), - er * (x => Reading(nr - 1, 0)), - ww * (x => Reading(nr, 1)) - ) - else if (nr != 0 && nw != 0) - choice ( - ww * (x => Reading(nr, nw + 1)), - er * (x => Reading(nr - 1, nw)) - ); - - private def Writing(nw: int): unit = choice ( - ew * (x => Reading(0, nw - 1)), - ww * (x => Writing(nw + 1)) - ); - - spawn < Reading(0, 0) >; - - } - - /** - * Main function. - */ - def main(args: Array[String]): unit = { - val random = new java.util.Random() - - def reader(i: int, rwlock: ReadWriteLock): unit = { - Thread.sleep(1 + random.nextInt(100)) - System.err.println("Reader " + i + " wants to read.") - rwlock.startRead - System.err.println("Reader " + i + " is reading.") - Thread.sleep(1 + random.nextInt(100)) - rwlock.endRead - System.err.println("Reader " + i + " has read.") - reader(i, rwlock) - } - - def writer(i: int, rwlock: ReadWriteLock): unit = { - Thread.sleep(1 + random.nextInt(100)) - System.err.println("Writer " + i + " wants to write.") - rwlock.startWrite - System.err.println("Writer " + i + " is writing.") - Thread.sleep(1 + random.nextInt(100)) - rwlock.endWrite - System.err.println("Writer " + i + " has written.") - writer(i, rwlock) - } - - val n = try { Integer.parseInt(args(0)) } catch { case _ => 0 } - if (n < 1 || 5 < n) { - Console.println("Usage: scala examples.pilib.rwlock <n> (n=1..5)") - exit - } - val rwlock = n match { - case 1 => new ReadWriteLock1 - case 2 => new ReadWriteLock2 - case 3 => new ReadWriteLock3 - case 4 => new ReadWriteLock4 - case 5 => new ReadWriteLock5 - } - List.range(0, 5) foreach (i => spawn < reader(i, rwlock) >) - List.range(0, 5) foreach (i => spawn < writer(i, rwlock) >) - } - -} - diff --git a/docs/examples/pilib/scheduler.scala b/docs/examples/pilib/scheduler.scala deleted file mode 100644 index fd8fd52600..0000000000 --- a/docs/examples/pilib/scheduler.scala +++ /dev/null @@ -1,150 +0,0 @@ -package examples.pilib - -import scala.concurrent.pilib._ - -object scheduler { - - /** - * Random number generator. - */ - val random = new util.Random() - - //***************** Scheduler ******************// - - /** - * A cell of the scheduler whose attached agent is allowed to start. - */ - def A(a: Chan[Unit], b: Chan[Unit])(d: Chan[Unit], c: Chan[Unit]) { - ///- ... complete here ... - choice ( a * { x => C(a, b)(d, c) }) - ///+ - } - - /** - * A cell of the scheduler in another intermediate state. - */ - def C(a: Chan[Unit], b: Chan[Unit])(d: Chan[Unit], c: Chan[Unit]) { - ///- ... complete here ... - choice (c * { x => B(a, b)(d, c) }) - ///+ - } - - /** - * A cell of the scheduler whose attached agent is allowed to finish. - */ - def B(a: Chan[Unit], b: Chan[Unit])(d: Chan[Unit], c: Chan[Unit]) { - ///- ... complete here ... - // choice (b * { x => D(a, b)(d, c) }) // incorrect naive solution - choice ( - b * { x => choice ( d(()) * A(a, b)(d, c) ) }, // b.'d.A - d(()) * (choice (b * { x => A(a, b)(d, c) })) // 'd.b.A - ) - ///+ - } - - /** - * A cell of the scheduler whose attached agent is not yet allowed to start. - */ - def D(a: Chan[Unit], b: Chan[Unit])(d: Chan[Unit], c: Chan[Unit]) { - ///- ... complete here ... - choice (d(()) * A(a, b)(d, c)) - ///+ - } - - //***************** Agents ******************// - - def agent(i: Int)(a: Chan[Unit], b: Chan[Unit]) { - // 50% chance that we sleep forever - if (i == 0 && random.nextInt(10) < 5) { - a.attach(x => println("Start and sleeps ----> " + i)) - Thread.sleep(random.nextInt(1000)) - a.write(()) - } - else { - a.attach(x => println("Start ----> " + i)) - b.attach(x => println("Stop -> " + i)) - Thread.sleep(random.nextInt(1000)) - a.write(()) - Thread.sleep(random.nextInt(1000)) - b.write(()) - agent(i)(a, b) - } - } - - //***************** Entry function ******************// - - /** - * Creates a scheduler for five agents (programs). - */ - - def main(args: Array[String]) { - val agentNb = 5 - val agents = List.range(0, agentNb) map agent - scheduleAgents(agents) - } - - //***************** Infrastructure *****************// - - /** - * A cell is modelled as a function that takes as parameters - * input and output channels and which returns nothing. - */ - type Cell = (Chan[Unit], Chan[Unit]) => Unit - - /** - * Creates a cell composed of two cells linked together. - */ - def join(cell1: Cell, cell2: Cell): Cell = - (l: Chan[Unit], r: Chan[Unit]) => { - val link = new Chan[Unit]; - spawn < cell1(l, link) | cell2(link, r) > - }; - - /** - * Links the output of a cell to its input. - */ - def close(cell: Cell) { - val a = new Chan[Unit] - cell(a, a) - } - - /** - * Creates a cell consisting of a chain of cells. - */ - def chain(cells: List[Cell]): Cell = - cells reduceLeft join - - /** - * Creates a cell consisting of a chain of cells. - */ - def makeRing(cells: List[Cell]): Unit = - close(chain(cells)) - - /** - * An agent is modelled as a function that takes as parameters channels to - * signal that it has started or finished. - */ - type Agent = (Chan[Unit], Chan[Unit]) => Unit - - /** - * Takes a list of agents and schedules them. - */ - def scheduleAgents(agents: List[Agent]) { - var firstAgent = true; - val cells = agents map (ag => { - val a = new Chan[Unit]; - val b = new Chan[Unit]; - spawn < ag(a, b) >; - (d: Chan[Unit], c: Chan[Unit]) => if (firstAgent) { - firstAgent = false; - A(a, b)(d, c) - } - else - D(a, b)(d, c) - }); - makeRing(cells) - } - -} - - diff --git a/docs/examples/pilib/semaphore.scala b/docs/examples/pilib/semaphore.scala deleted file mode 100644 index 951c90e8d4..0000000000 --- a/docs/examples/pilib/semaphore.scala +++ /dev/null @@ -1,72 +0,0 @@ -package examples.pilib - -import scala.concurrent.pilib._ - -/** Solution of exercise session 6 (first question). */ -object semaphore { - - class Signal extends Chan[Unit] { - def send = write(()) - def receive = read - } - - /** Interface. */ - trait Semaphore { - def get: Unit - def release: Unit - } - - /** First implementation. */ - class Sem1 extends Semaphore { - - private val g = new Signal - private val r = new Signal - - def get: Unit = g.send - def release: Unit = r.send - - private def Sched: Unit = choice ( - g * (x => { r.receive; Sched }), - r * (x => Sched) - ) - spawn< Sched > - } - - /** Second implementation. */ - class Sem2 extends Semaphore { - - private val a = new Signal - private val na = new Signal - - def get { a.receive; spawn< na.send > } - def release: Unit = choice ( - a * (x => spawn< a.send >), - na * (x => spawn< a.send >) - ) - spawn< a.send > - } - - /** Test program. */ - def main(args: Array[String]) { - val random = new util.Random() - val sem = new Sem2 - def mutex(p: => Unit) { sem.get; p; sem.release } - - spawn< { - Thread.sleep(1 + random.nextInt(100)); - mutex( { - println("a1"); - Thread.sleep(1 + random.nextInt(100)); - println("a2") - } ) - } | { - Thread.sleep(1 + random.nextInt(100)); - mutex( { - println("b1"); - Thread.sleep(1 + random.nextInt(100)); - println("b2") - } ) - } >; - } -} - diff --git a/docs/examples/pilib/twoPlaceBuffer.scala b/docs/examples/pilib/twoPlaceBuffer.scala deleted file mode 100644 index 255f70ca06..0000000000 --- a/docs/examples/pilib/twoPlaceBuffer.scala +++ /dev/null @@ -1,67 +0,0 @@ -package examples.pilib - -import scala.concurrent.pilib._ - -/** Two-place buffer specification and implementation. */ -object twoPlaceBuffer extends Application { - - /** - * Specification. - */ - def Spec[A](in: Chan[A], out: Chan[A]) { - - def B0: Unit = choice ( - in * (x => B1(x)) - ) - - def B1(x: A): Unit = choice ( - out(x) * (B0), - in * (y => B2(x, y)) - ) - - def B2(x: A, y: A): Unit = choice ( - out(x) * (B1(y)) - ) - - B0 - } - - /** - * Implementation using two one-place buffers. - */ - def Impl[A](in: Chan[A], out: Chan[A]) { - ///- ... complete here ... - // one-place buffer - def OnePlaceBuffer[A](in: Chan[A], out: Chan[A]) { - def B0: Unit = choice ( in * (x => B1(x)) ) - def B1(x: A): Unit = choice ( out(x) * (B0)) - B0 - } - val hidden = new Chan[A] - spawn < OnePlaceBuffer(in, hidden) | OnePlaceBuffer(hidden, out) > - ///+ - } - - val random = new util.Random() - - def Producer(n: Int, in: Chan[String]) { - Thread.sleep(random.nextInt(1000)) - val msg = "" + n - choice (in(msg) * {}) - Producer(n + 1, in) - } - - def Consumer(out: Chan[String]) { - Thread.sleep(random.nextInt(1000)) - choice (out * { msg => () }) - Consumer(out) - } - - val in = new Chan[String] - in.attach(s => println("put " + s)) - val out = new Chan[String] - out.attach(s => println("get " + s)) - //spawn < Producer(0, in) | Consumer(out) | Spec(in, out) > - spawn < Producer(0, in) | Consumer(out) | Impl(in, out) > - -} diff --git a/docs/examples/plugintemplate/build.xml b/docs/examples/plugintemplate/build.xml deleted file mode 100644 index 37c8441ce3..0000000000 --- a/docs/examples/plugintemplate/build.xml +++ /dev/null @@ -1,265 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<project name="plugintemplate" default="pack"> - <!-- Edit the file plugin.properties to set - - scala.home - - plugin.name - - plugin.commandname - - plugin.description - - plugin.mainclass - - version numbers - --> - <property file="${basedir}/plugin.properties"/> - - <property name="version" value="${version.major}.${version.minor}"/> - - <taskdef resource="scala/tools/ant/antlib.xml"> - <classpath> - <pathelement location="${scala.home}/lib/scala-compiler.jar"/> - <pathelement location="${scala.home}/lib/scala-library.jar"/> - </classpath> - </taskdef> - - - <!-- ================================================================= - End-user targets - ================================================================== --> - - <target name="build" depends="build.main"/> - <target name="build.all" depends="build.done"/> - <target name="test" depends="test.all"/> - <target name="guitest" depends="guitest.all"/> - <target name="doc" depends="doc.done"/> - <target name="pack" depends="pack.done"/> - <target name="dist" depends="dist.done"/> - <target name="clean" depends="clean.all"/> - - <!-- ================================================================= - Build targets - ================================================================== --> - - <target name="build.main"> - <mkdir dir="build/build.main"/> - <scalac srcdir="src" - destdir="build/build.main" - includes="**/*.scala"> - <classpath> - <pathelement location="${scala.home}/lib/scala-library.jar"/> - <pathelement location="${scala.home}/lib/scala-compiler.jar"/> - </classpath> - </scalac> - </target> - - <target name="build.test" depends="build.main"> - <mkdir dir="build/build.test"/> - <scalac srcdir="test" - destdir="build/build.test" - includes="**/*.scala"> - <classpath> - <pathelement location="${scala.home}/lib/scala-library.jar"/> - <pathelement location="${scala.home}/lib/scala-compiler.jar"/> - <pathelement location="lib/scalatest.jar"/> - <pathelement location="build/build.main"/> - </classpath> - </scalac> - </target> - - <target name="build.examples" depends="build.test"> - <mkdir dir="build/build.examples"/> - <scalac srcdir="doc/examples" - destdir="build/build.examples" - includes="**/*.scala"> - <classpath> - <pathelement location="${scala.home}/lib/scala-library.jar"/> - <pathelement location="${scala.home}/lib/scala-compiler.jar"/> - <pathelement location="build/build.main"/> - </classpath> - </scalac> - </target> - - <target name="build.done" depends="build.examples"/> - - <!-- ================================================================= - Test targets - ================================================================== --> - - <target name="test.all" depends="build.done"> - <!-- fork="true" is good for running the graphical mode --> - <java classname="org.scalatest.tools.Runner" fork="true"> - <classpath> - <pathelement location="${scala.home}/lib/scala-compiler.jar" /> - <pathelement location="${scala.home}/lib/scala-library.jar" /> - <pathelement location="lib/scalatest.jar" /> - <pathelement location="build/build.main" /> - <pathelement location="build/build.test" /> - </classpath> - - <arg value="-p" /> - <arg value="build/build.test" /> - - <arg value="-o" /> - </java> - </target> - - <target name="guitest.all" depends="build.done"> - <!-- fork="true" is good for running the graphical mode --> - <java classname="org.scalatest.tools.Runner" fork="true"> - <classpath> - <pathelement location="${scala.home}/lib/scala-compiler.jar" /> - <pathelement location="${scala.home}/lib/scala-library.jar" /> - <pathelement location="lib/scalatest.jar" /> - <pathelement location="build/build.main" /> - <pathelement location="build/build.test" /> - </classpath> - - <arg value="-p" /> - <arg value="build/build.test" /> - - <arg value="-g" /> - </java> - </target> - - <!-- ================================================================= - Doc targets - ================================================================== --> - - <target name="doc.main"> - <mkdir dir="doc/api"/> - <scaladoc srcdir="src" - destdir="doc/api" - includes="**/*.scala"> - <classpath> - <pathelement location="${scala.home}/lib/scala-library.jar"/> - <pathelement location="${scala.home}/lib/scala-compiler.jar"/> - </classpath> - </scaladoc> - </target> - - <target name="doc.done" depends="doc.main"/> - - <!-- ================================================================= - Pack targets - ================================================================== --> - - <target name="pack.main" depends="build.done"> - <mkdir dir="build/pack"/> - <jar destfile="build/pack/${plugin.name}.jar"> - <fileset dir="build/build.main"/> - <fileset file="plugin.properties"/> - <fileset file="misc/scalac-plugin.xml"/> - </jar> - </target> - - <target name="pack.src" depends="pack.main"> - <jar destfile="build/pack/${plugin.name}-src.jar" - basedir="src" - includes="**/*.scala"/> - </target> - - <target name="pack.done" depends="pack.src"/> - - <!-- ================================================================= - Dist targets - ================================================================== --> - - <target name="dist.bin" depends="test.all,pack.done,doc.done"> - <mkdir dir="build/toolscript"/> - <scalascript - file="build/toolscript/${plugin.commandname}" - class="${plugin.mainclass}"/> - <chmod dir="build/toolscript" perm="a+rx" excludes="*.bat"/> - </target> - - <target name="dist.archive" depends="dist.bin"> - <mkdir dir="build/dist"/> - <tar destfile="build/dist/${plugin.name}-${version}.tgz" - compression="gzip"> - <tarfileset prefix="lib" dir="build/pack" - includes="${plugin.name}.jar"/> - <tarfileset prefix="src" dir="build/pack" - includes="${plugin.name}-src.jar"/> - <tarfileset prefix="doc/${plugin.name}" dir="doc" - includes="README"/> - <tarfileset prefix="doc/${plugin.name}" dir="doc" - includes="examples/**"/> - <tarfileset prefix="doc/${plugin.name}" dir="doc" - includes="api/**"/> - <tarfileset prefix="bin" dir="build/toolscript" - includes="${plugin.commandname}" mode="755"/> - <tarfileset prefix="bin" dir="build/toolscript" - includes="${plugin.commandname}.bat"/> - <tarfileset prefix="misc/scala-devel/plugins" dir="build/pack" - includes="${plugin.name}.jar"/> - </tar> - </target> - - <target name="dist.sbaz" depends="dist.archive"> - <sbaz file="build/dist/${plugin.name}-${version}.sbp" - adfile="build/dist/${plugin.name}-${version}.advert" - name="${plugin.name}" - version="${version}" - depends="scala-devel" - desc="${plugin.description}" - link="${plugin.sbazbaseurl}/${plugin.name}-${version}.sbp"> - <libset dir="build/pack" includes="${plugin.name}.jar"/> - <srcset dir="build/pack" includes="${plugin.name}-src.jar"/> - <docset dir="doc" includes="README"/> - <docset dir="doc" includes="examples/**"/> - <docset dir="doc" includes="api/**"/> - <binset dir="build/toolscript"/> - <looseset destination="misc/scala-devel/plugins"> - <fileset file="build/pack/${plugin.name}.jar"/> - </looseset> - </sbaz> - </target> - - <target name="dist.done" depends="dist.sbaz"/> - - <!-- ================================================================= - Local installation - ================================================================== --> - - <target name="install" depends="dist.done"> - <exec executable="sbaz"> - <arg line="-v install -f build/dist/${plugin.name}-${version}.sbp"/> - </exec> - </target> - - <target name="uninstall"> - <exec executable="sbaz"> - <arg line="remove ${plugin.name}"/> - </exec> - </target> - - <!-- ================================================================= - Clean targets - ================================================================== --> - - <target name="clean.build"> - <delete dir="build/build.main" includeemptydirs="yes" - quiet="yes" failonerror="no"/> - <delete dir="build/build.test" includeemptydirs="yes" - quiet="yes" failonerror="no"/> - <delete dir="build/build.examples" includeemptydirs="yes" - quiet="yes" failonerror="no"/> - </target> - - <target name="clean.pack" depends="clean.build"> - <delete dir="build/pack" includeemptydirs="yes" - quiet="yes" failonerror="no"/> - </target> - - <target name="clean.dist" depends="clean.pack"> - <delete dir="build/dist" includeemptydirs="yes" - quiet="yes" failonerror="no"/> - <delete dir="build/toolscript" includeemptydirs="yes" - quiet="yes" failonerror="no"/> - </target> - - <target name="clean.doc"> - <delete dir="doc/api" includeemptydirs="yes" - quiet="yes" failonerror="no"/> - </target> - - <target name="clean.all" depends="clean.dist,clean.doc"/> -</project> diff --git a/docs/examples/plugintemplate/doc/README b/docs/examples/plugintemplate/doc/README deleted file mode 100644 index 958f71282b..0000000000 --- a/docs/examples/plugintemplate/doc/README +++ /dev/null @@ -1,68 +0,0 @@ -Scala compiler plugin template ------------------------------- - -This project is a template that can be used for creating compiler -plugins for the Scala compiler. - - -Installation ------------- -To install the compiler plugin, run "ant install". This will create -an sbaz package for the template plugin and install it in the scala -installation available in your PATH. -The install command will also create a script for running the plugin -as standalone application. The command is called "runplugintemplate" -and available in your scala installation as well. -To uninstall the plugin again, run "and uninstall". - -Alternatively, copy the file build/pack/plugintemplate.jar, generated -by "ant pack", to the directory misc/scala-devel/plugins of your -scala distribution. The scala compiler will then find and integrate -the new plugin. - -Customization -------------- -The following files need to be edited when creating a new plugin -- plugin.properties -- misc/scalac-plugin.xml -- src / test / doc/examples: The source files of the template plugin - are located a package called "plugintemplate". This will most likely - be changed for new plugins. - -When using eclipse for development, make sure "scala-compiler.jar" is -in the Java Build Path: Right-Click the project and select "Properties". -Then go to "Java Build Path" -> "Libraries" and add the jar file -"eclipse/plugins/ch.epfl.lamp.sdt.core[..]/lib/scala-compiler.jar". - -Traverse, Transform, Check --------------------------- -There are several pre-defined components that can be used to code -the behavior of a plugin: -- TemplateTraverseComponent: a template for tree traversers. Used - to analyze and collect data about compiler trees. - -> implement the "check" method - -- TemplateTransformComponent: a template for tree transformers. - -> implement "preTransform" and / or "postTransform" - -- TemplateInfoTransformComponent: also a tree transformer, which - additionally is an InfoTransformer. Allows changing the type - of some symbols for later phases. - -> implement "preTransform" and / or "postTransform", and the - "apply" method of the "infoTransformer". - -- TemplateAnnotationChecker: a plugin for the typechecker, useful - for pluggable type systems. Computes the subtyping between two - annotated types, and allows providing inferred type information. - -> implement "annotationsConform" and optionally "addAnnotations" - -- TemplateComponent: the most general component. Can do anything it - likes with the CompilationUnits. - -> implement the "run" method - -Ant tasks ---------- -"build.xml" defines Ant tasks for building, testing and packing a -plugin. The tests are written using the ScalaTest framework -(http://www.artima.com/scalatest/). -Run the tests using "ant test", or "ant guitest". diff --git a/docs/examples/plugintemplate/doc/examples/plugintemplate/examples/BasicExample.scala b/docs/examples/plugintemplate/doc/examples/plugintemplate/examples/BasicExample.scala deleted file mode 100644 index d1f6c91cdc..0000000000 --- a/docs/examples/plugintemplate/doc/examples/plugintemplate/examples/BasicExample.scala +++ /dev/null @@ -1,8 +0,0 @@ -package plugintemplate.examples - -/** An example demonstrating the fancy features of the new - * compiler plugin. - */ -class BasicExample { - def foo = () -} diff --git a/docs/examples/plugintemplate/lib/scalatest.jar.desired.sha1 b/docs/examples/plugintemplate/lib/scalatest.jar.desired.sha1 deleted file mode 100644 index 14c20f874f..0000000000 --- a/docs/examples/plugintemplate/lib/scalatest.jar.desired.sha1 +++ /dev/null @@ -1 +0,0 @@ -8b6ba65c8146217333f0762087fe2340d572e832 ?scalatest.jar diff --git a/docs/examples/plugintemplate/misc/scalac-plugin.xml b/docs/examples/plugintemplate/misc/scalac-plugin.xml deleted file mode 100644 index bad4e87327..0000000000 --- a/docs/examples/plugintemplate/misc/scalac-plugin.xml +++ /dev/null @@ -1,4 +0,0 @@ -<plugin> - <name>plugintemplate</name> - <classname>plugintemplate.TemplatePlugin</classname> -</plugin> diff --git a/docs/examples/plugintemplate/plugin.properties b/docs/examples/plugintemplate/plugin.properties deleted file mode 100644 index 131f96110f..0000000000 --- a/docs/examples/plugintemplate/plugin.properties +++ /dev/null @@ -1,10 +0,0 @@ -scala.home=../../../build/pack - -plugin.name=plugintemplate -plugin.commandname=runplugintemplate -plugin.description=A template compiler plugin saying hello to the World -plugin.mainclass=plugintemplate.standalone.Main -plugin.sbazbaseurl=http://scala.epfl.ch/downloads/packages - -version.major=0 -version.minor=1 diff --git a/docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala b/docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala deleted file mode 100644 index ed078a03d7..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/PluginProperties.scala +++ /dev/null @@ -1,61 +0,0 @@ -package plugintemplate - -import java.util.Properties - -/** A utility to load properties of this plugin via the property - * file "plugin.properties" - */ -object PluginProperties { - private val propFilename = "plugin.properties" - - val pluginName = getOrElse("plugin.name", "(name_unknown)") - val pluginDescription = getOrElse("plugin.description", "(plugin description not found)") - val pluginCommand = getOrElse("plugin.commandname", "(command_unknown)") - val versionString = { - val default = "(version_unknown)" - props match { - case Some(p) => - val major = p.getProperty("version.major") - val minor = p.getProperty("version.minor") - if ((major eq null) || (minor eq null)) default - else major +"."+ minor - case None => default - } - } - - private def getOrElse(property: String, default: String) = { - props match { - case Some(p) if (p.getProperty(property) != null) => - p.getProperty(property) - case _ => - default - } - } - - private lazy val props: Option[Properties] = { - /** Running from JAR file: the properties file should be in the - * jar as well - */ - var stream = this.getClass.getResourceAsStream("/"+ propFilename) - if (stream == null) { - /** Running from .class files: expect classfiles to be in - * directory [...]/build/build.main, and [...] to contain - * the properties file. - */ - try { - val current = this.getClass.getClassLoader.getResource(".") - val dir = new java.io.File(current.toURI) - // dir will be [...]/build/build.main/ - stream = new java.io.FileInputStream(dir.getParentFile.getParent +"/"+ propFilename) - } catch { - case _ => () - } - } - if (stream == null) None - else { - val p = new Properties - p.load(stream) - Some(p) - } - } -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateAnnotationChecker.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateAnnotationChecker.scala deleted file mode 100644 index 6cd3472675..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplateAnnotationChecker.scala +++ /dev/null @@ -1,20 +0,0 @@ -package plugintemplate - -import scala.tools.nsc.Global - -abstract class TemplateAnnotationChecker { - val global: Global - import global._ - - object checker extends AnnotationChecker { - def annotationsConform(tpe1: Type, tpe2: Type): Boolean = { - println("checking: "+ tpe1 +" <: "+ tpe2) - true - } - - override def addAnnotations(tree: Tree, tpe: Type): Type = { - println("adding annot to "+ tree.symbol) - tpe - } - } -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala deleted file mode 100644 index b63f3203b5..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplateComponent.scala +++ /dev/null @@ -1,35 +0,0 @@ -package plugintemplate - -import scala.tools.nsc._ -import scala.tools.nsc.plugins.PluginComponent - -/** This class shows how to implement a compiler component that - * can be used in a compiler plugin. If the plugin uses a tree - * transformer and / or an InfoTransformer, look at the two - * classes <code>TemplateTransformComponent</code> and - * <code>TemplateInfoTransformComponent</code>. - * - * @todo Adapt the name of this class to the plugin, and implement it. - */ -class TemplateComponent(val global: Global) extends PluginComponent { - import global._ - - val runsAfter = List[String]("refchecks") - - /** The name of this plugin phase - * @todo Adapt to specific plugin. - */ - val phaseName = "plugintemplate" - - def newPhase(prev: Phase) = new Phase(prev) { - def name = phaseName - - /** The implementation of this Phase's behavior - * - * @todo Implementation. - */ - def run { - println("Hello from phase "+ name) - } - } -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateInfoTransformComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateInfoTransformComponent.scala deleted file mode 100644 index 71069aed6f..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplateInfoTransformComponent.scala +++ /dev/null @@ -1,79 +0,0 @@ -package plugintemplate - -import scala.tools.nsc._ -import scala.tools.nsc.plugins.PluginComponent -import scala.tools.nsc.transform.InfoTransform -// import scala.tools.nsc.transform.TypingTransformers - -/** This class implements a plugin component using tree transformers and - * InfoTransformer. An InfoTransformer will be automatically created - * and registered in <code>SymbolTable.infoTransformers</code>. If - * a <code>Typer</code> is needed during transformation, the component - * should mix in <code>TypingTransformers</code>. This provides a local - * variable <code>localTyper: Typer</code> that is always updated to - * the current context. - * - * @todo Adapt the name of this class to the plugin, and implement it. - */ -class TemplateInfoTransformComponent(val global: Global) extends PluginComponent - // with TypingTransformers - with InfoTransform { - - import global._ - import global.definitions._ - - val runsAfter = List[String]("refchecks") - /** The phase name of the compiler plugin - * @todo Adapt to specific plugin. - */ - val phaseName = "plugintemplateinfotransform" - - def transformInfo(sym: Symbol, tp: Type): Type = infoTransformer.mapOver(tp) - - def newTransformer(unit: CompilationUnit) = new TemplateTransformer - - /** The type transformation applied by this component. The trait InfoTransform - * will create an instance of InfoTransformer applying this TypeMap. The type - * map will be applied when computing a symbol's type in all phases - * <em>after</em> "plugintemplateinfotransform". - * - * @todo Implement. - */ - private val infoTransformer = new TypeMap { - def apply(tp: Type): Type = tp match { - case MethodType(pts, rt) => - println("methodType (_, _, ..) => "+ rt) - tp - case _ => mapOver(tp) - } - } - - /** The tree transformer that implements the behavior of this - * component. Change the superclass to <code>TypingTransformer</code> - * to make a local typechecker <code>localTyper</code> available. - * - * @todo Implement. - */ - class TemplateTransformer extends /*Typing*/ Transformer { - /** When using <code>preTransform</code>, each node is - * visited before its children. - */ - def preTransform(tree: Tree): Tree = tree match { - case ValDef(_, name, _, _) => - println("pre-info-transforming valdef "+ name) - tree - case _ => tree - } - - /** When using <code>postTransform</code>, each node is - * visited after its children. - */ - def postTransform(tree: Tree): Tree = tree match { - case _ => tree - } - - override def transform(tree: Tree): Tree = { - postTransform(super.transform(preTransform(tree))) - } - } -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala deleted file mode 100644 index 6cda37d4e3..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplatePlugin.scala +++ /dev/null @@ -1,52 +0,0 @@ -package plugintemplate - -import scala.tools.nsc.Global -import scala.tools.nsc.plugins.Plugin - -/** A class describing the compiler plugin - * - * @todo Adapt the name of this class to the plugin being - * implemented - */ -class TemplatePlugin(val global: Global) extends Plugin { - /** The name of this plugin. Extracted from the properties file. */ - val name = PluginProperties.pluginName - - val runsAfter = List[String]("refchecks") - - /** A short description of the plugin, read from the properties file */ - val description = PluginProperties.pluginDescription - - /** @todo A description of the plugin's options */ - override val optionsHelp = Some( - " -P:"+ name +":option sets some option for this plugin") - - /** @todo Implement parsing of plugin options */ - override def processOptions(options: List[String], error: String => Unit) { - super.processOptions(options, error) - } - - /** The compiler components that will be applied when running - * this plugin - * - * @todo Adapt to the plugin being implemented - */ - val components = TemplatePlugin.components(global) - - val checker = new TemplateAnnotationChecker { - val global: TemplatePlugin.this.global.type = TemplatePlugin.this.global - } - global.addAnnotationChecker(checker.checker) -} - -object TemplatePlugin { - /** Yields the list of Components to be executed in this plugin - * - * @todo: Adapt to specific implementation. - */ - def components(global: Global) = - List(new TemplateComponent(global), - new TemplateTraverseComponent(global), - new TemplateTransformComponent(global), - new TemplateInfoTransformComponent(global)) -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateTransformComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateTransformComponent.scala deleted file mode 100644 index 7c2630dc16..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplateTransformComponent.scala +++ /dev/null @@ -1,58 +0,0 @@ -package plugintemplate - -import scala.tools.nsc._ -import scala.tools.nsc.plugins.PluginComponent -import scala.tools.nsc.transform.Transform -// import scala.tools.nsc.transform.TypingTransformers - -/** This class implements a plugin component using tree transformers. If - * a <code>Typer</code> is needed during transformation, the component - * should mix in <code>TypingTransformers</code>. This provides a local - * variable <code>localTyper: Typer</code> that is always updated to - * the current context. - * - * @todo Adapt the name of this class to the plugin, and implement it. - */ -class TemplateTransformComponent(val global: Global) extends PluginComponent - // with TypingTransformers - with Transform { - import global._ - import global.definitions._ - - val runsAfter = List[String]("refchecks") - /** The phase name of the compiler plugin - * @todo Adapt to specific plugin. - */ - val phaseName = "plugintemplatetransform" - - def newTransformer(unit: CompilationUnit) = new TemplateTransformer - - /** The tree transformer that implements the behavior of this - * component. Change the superclass to <code>TypingTransformer</code> - * to make a local typechecker <code>localTyper</code> available. - * - * @todo Implement. - */ - class TemplateTransformer extends /*Typing*/ Transformer { - /** When using <code>preTransform</code>, each node is - * visited before its children. - */ - def preTransform(tree: Tree): Tree = tree match { - case _ => tree - } - - /** When using <code>postTransform</code>, each node is - * visited after its children. - */ - def postTransform(tree: Tree): Tree = tree match { - case New(tpt) => - println("post-transforming new "+ tpt) - tree - case _ => tree - } - - override def transform(tree: Tree): Tree = { - postTransform(super.transform(preTransform(tree))) - } - } -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/TemplateTraverseComponent.scala b/docs/examples/plugintemplate/src/plugintemplate/TemplateTraverseComponent.scala deleted file mode 100644 index 400daf7437..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/TemplateTraverseComponent.scala +++ /dev/null @@ -1,32 +0,0 @@ -package plugintemplate - -import scala.tools.nsc._ -import scala.tools.nsc.plugins.PluginComponent - -/** This class implements a plugin component using a tree - * traverser */ -class TemplateTraverseComponent (val global: Global) extends PluginComponent { - import global._ - import global.definitions._ - - val runsAfter = List[String]("refchecks") - /** The phase name of the compiler plugin - * @todo Adapt to specific plugin. - */ - val phaseName = "plugintemplatetraverse" - - def newPhase(prev: Phase): Phase = new TraverserPhase(prev) - class TraverserPhase(prev: Phase) extends StdPhase(prev) { - def apply(unit: CompilationUnit) { - newTraverser().traverse(unit.body) - } - } - - def newTraverser(): Traverser = new ForeachTreeTraverser(check) - - def check(tree: Tree): Unit = tree match { - case Apply(fun, args) => - println("traversing application of "+ fun) - case _ => () - } -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/standalone/Main.scala b/docs/examples/plugintemplate/src/plugintemplate/standalone/Main.scala deleted file mode 100644 index 0bfcbf53c7..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/standalone/Main.scala +++ /dev/null @@ -1,44 +0,0 @@ -package plugintemplate.standalone - -import plugintemplate.PluginProperties -import scala.tools.nsc.CompilerCommand -import scala.tools.nsc.Settings - -/** An object for running the plugin as standalone application. - * - * @todo: print, parse and apply plugin options !!! - * ideally re-use the TemplatePlugin (-> runsAfter, optionsHelp, - * processOptions, components, annotationChecker) instead of - * duplicating it here and in PluginRunner. - */ -object Main { - def main(args: Array[String]) { - val settings = new Settings - - val command = new CompilerCommand(args.toList, settings) { - /** The command name that will be printed in the usage message. - * This is automatically set to the value of 'plugin.commandname' in the - * file build.properties. - */ - override val cmdName = PluginProperties.pluginCommand - } - - if (!command.ok) - return() - - /** The version number of this plugin is read from the properties file - */ - if (settings.version.value) { - println(command.cmdName +" version "+ PluginProperties.versionString) - return() - } - if (settings.help.value) { - println(command.usageMsg) - return() - } - - val runner = new PluginRunner(settings) - val run = new runner.Run - run.compile(command.files) - } -} diff --git a/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala b/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala deleted file mode 100644 index 06fe669cbd..0000000000 --- a/docs/examples/plugintemplate/src/plugintemplate/standalone/PluginRunner.scala +++ /dev/null @@ -1,36 +0,0 @@ -package plugintemplate.standalone - -import plugintemplate.{TemplateAnnotationChecker, TemplatePlugin} -import scala.tools.nsc.{Global, Settings, SubComponent} -import scala.tools.nsc.reporters.{ConsoleReporter, Reporter} - -/** This class is a compiler that will be used for running - * the plugin in standalone mode. - */ -class PluginRunner(settings: Settings, reporter: Reporter) -extends Global(settings, reporter) { - def this(settings: Settings) = this(settings, new ConsoleReporter(settings)) - - val annotChecker = new TemplateAnnotationChecker { - val global: PluginRunner.this.type = PluginRunner.this - } - addAnnotationChecker(annotChecker.checker) - - /** The phases to be run. - * - * @todo: Adapt to specific plugin implementation - */ - override protected def computeInternalPhases() { - phasesSet += syntaxAnalyzer - phasesSet += analyzer.namerFactory - phasesSet += analyzer.typerFactory - phasesSet += superAccessors // add super accessors - phasesSet += pickler // serialize symbol tables - phasesSet += refChecks // perform reference and override checking, translate nested objects - - for (phase <- TemplatePlugin.components(this)) { - phasesSet += phase - } - } - -} diff --git a/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala b/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala deleted file mode 100644 index a07796a7f2..0000000000 --- a/docs/examples/plugintemplate/test/plugintemplate/PluginPropertiesSuite.scala +++ /dev/null @@ -1,14 +0,0 @@ -package plugintemplate - -import org.scalatest.Suite - -class PluginPropertiesSuite extends Suite { - def testProperties() { - expect("A template compiler plugin saying hello to the World") { - PluginProperties.pluginDescription - } - expect("0.1") { - PluginProperties.versionString - } - } -} diff --git a/docs/examples/plugintemplate/test/plugintemplate/TemplatePluginSuite.scala b/docs/examples/plugintemplate/test/plugintemplate/TemplatePluginSuite.scala deleted file mode 100644 index 06916f9dd3..0000000000 --- a/docs/examples/plugintemplate/test/plugintemplate/TemplatePluginSuite.scala +++ /dev/null @@ -1,22 +0,0 @@ -package plugintemplate - -import org.scalatest.Suite -import org.scalatest.Ignore - -class TemplatePluginSuite extends Suite { - def testName() { - import scala.tools.nsc.{Global, Settings} - import scala.tools.nsc.reporters.ConsoleReporter - val settings = new Settings - val compiler = new Global(settings, new ConsoleReporter(settings)) - val plugin = new TemplatePlugin(compiler) - expect("plugintemplate") { - plugin.name - } - } - - @Ignore - def testFail() { - expect(1) { 2 } - } -} diff --git a/docs/examples/sort.scala b/docs/examples/sort.scala deleted file mode 100644 index 9a928f1107..0000000000 --- a/docs/examples/sort.scala +++ /dev/null @@ -1,48 +0,0 @@ -package examples - -object sort { - - def sort(a: Array[Int]) { - - def swap(i: Int, j: Int) { - val t = a(i); a(i) = a(j); a(j) = t - } - - def sort1(l: Int, r: Int) { - val pivot = a((l + r) / 2) - var i = l - var j = r - while (i <= j) { - while (a(i) < pivot) { i += 1 } - while (a(j) > pivot) { j -= 1 } - if (i <= j) { - swap(i, j) - i += 1 - j -= 1 - } - } - if (l < j) sort1(l, j) - if (j < r) sort1(i, r) - } - - if (a.length > 0) - sort1(0, a.length - 1) - } - - def println(ar: Array[Int]) { - def print1 = { - def iter(i: Int): String = - ar(i) + (if (i < ar.length-1) "," + iter(i+1) else "") - if (ar.length == 0) "" else iter(0) - } - Console.println("[" + print1 + "]") - } - - def main(args: Array[String]) { - val ar = Array(6, 2, 8, 5, 1) - println(ar) - sort(ar) - println(ar) - } - -} diff --git a/docs/examples/sort1.scala b/docs/examples/sort1.scala deleted file mode 100644 index 39e5519fe0..0000000000 --- a/docs/examples/sort1.scala +++ /dev/null @@ -1,22 +0,0 @@ -package examples - -object sort1 { - - def sort(a: List[Int]): List[Int] = { - if (a.length < 2) - a - else { - val pivot = a(a.length / 2) - sort(a.filter(x => x < pivot)) ::: - a.filter(x => x == pivot) ::: - sort(a.filter(x => x > pivot)) - } - } - - def main(args: Array[String]) { - val xs = List(6, 2, 8, 5, 1) - println(xs) - println(sort(xs)) - } - -} diff --git a/docs/examples/sort2.scala b/docs/examples/sort2.scala deleted file mode 100644 index e0016088bb..0000000000 --- a/docs/examples/sort2.scala +++ /dev/null @@ -1,25 +0,0 @@ -package examples - -object sort2 { - - def sort(a: List[Int]): List[Int] = { - if (a.length < 2) - a - else { - val pivot = a(a.length / 2) - def lePivot(x: Int) = x < pivot - def gtPivot(x: Int) = x > pivot - def eqPivot(x: Int) = x == pivot - sort(a filter lePivot) ::: - (a filter eqPivot) ::: - sort(a filter gtPivot) - } - } - - def main(args: Array[String]) { - val xs = List(6, 2, 8, 5, 1, 8) - println(xs) - println(sort(xs)) - } - -} diff --git a/docs/examples/swing/ButtonApp.scala b/docs/examples/swing/ButtonApp.scala deleted file mode 100644 index 96799b24f2..0000000000 --- a/docs/examples/swing/ButtonApp.scala +++ /dev/null @@ -1,24 +0,0 @@ -package examples.swing - -import java.awt.Dimension - -import swing._ -import swing.event._ - -object ButtonApp extends SimpleSwingApplication { - def top = new MainFrame { - title = "My Frame" - contents = new GridPanel(2, 2) { - hGap = 3 - vGap = 3 - contents += new Button { - text = "Press Me!" - reactions += { - case ButtonClicked(_) => text = "Hello Scala" - } - } - } - size = new Dimension(300, 80) - } -} - diff --git a/docs/examples/swing/CelsiusConverter.scala b/docs/examples/swing/CelsiusConverter.scala deleted file mode 100644 index b4a62fb366..0000000000 --- a/docs/examples/swing/CelsiusConverter.scala +++ /dev/null @@ -1,42 +0,0 @@ -package examples.swing - -import swing._ -import event._ - -/** A GUI app to convert celsius to centigrade - */ -object CelsiusConverter extends SimpleSwingApplication { - def top = new MainFrame { - title = "Convert Celsius to Fahrenheit" - val tempCelsius = new TextField - val celsiusLabel = new Label { - text = "Celsius" - border = Swing.EmptyBorder(5, 5, 5, 5) - } - val convertButton = new Button { - text = "Convert"//new javax.swing.ImageIcon("c:\\workspace\\gui\\images\\convert.gif") - //border = Border.Empty(5, 5, 5, 5) - } - val fahrenheitLabel = new Label { - text = "Fahrenheit " - border = Swing.EmptyBorder(5, 5, 5, 5) - listenTo(convertButton, tempCelsius) - - def convert() { - val c = Integer.parseInt(tempCelsius.text) - val f = c * 9 / 5 + 32 - text = "<html><font color = red>"+f+"</font> Fahrenheit</html>" - } - - reactions += { - case ButtonClicked(_) | EditDone(_) => convert() - } - } - contents = new GridPanel(2,2) { - contents.append(tempCelsius, celsiusLabel, convertButton, fahrenheitLabel) - border = Swing.EmptyBorder(10, 10, 10, 10) - } - //defaultButton = Some(convertButton) - } -} - diff --git a/docs/examples/swing/CelsiusConverter2.scala b/docs/examples/swing/CelsiusConverter2.scala deleted file mode 100644 index 3630d61b61..0000000000 --- a/docs/examples/swing/CelsiusConverter2.scala +++ /dev/null @@ -1,36 +0,0 @@ -package examples.swing - -import swing._ -import event._ - -object CelsiusConverter2 extends SimpleSwingApplication { - def newField = new TextField { - text = "0" - columns = 5 - horizontalAlignment = Alignment.Right - } - val celsius = newField - val fahrenheit = newField - - listenTo(fahrenheit, celsius) - reactions += { - case EditDone(`fahrenheit`) => - val f = Integer.parseInt(fahrenheit.text) - val c = (f - 32) * 5 / 9 - celsius.text = c.toString - case EditDone(`celsius`) => - val c = Integer.parseInt(celsius.text) - val f = c * 9 / 5 + 32 - fahrenheit.text = f.toString - } - - lazy val ui = new FlowPanel(celsius, new Label(" Celsius = "), - fahrenheit, new Label(" Fahrenheit")) { - border = Swing.EmptyBorder(15, 10, 10, 10) - } - def top = new MainFrame { - title = "Convert Celsius / Fahrenheit" - contents = ui - } -} - diff --git a/docs/examples/swing/ComboBoxes.scala b/docs/examples/swing/ComboBoxes.scala deleted file mode 100644 index c6ee19013a..0000000000 --- a/docs/examples/swing/ComboBoxes.scala +++ /dev/null @@ -1,86 +0,0 @@ -package examples.swing - -import swing._ -import event._ -import java.util.Date -import java.awt.Color -import java.text.SimpleDateFormat -import javax.swing.{Icon, ImageIcon} - -/** - * Demonstrates how to use combo boxes and custom item renderers. - * - * TODO: clean up layout - */ -object ComboBoxes extends SimpleSwingApplication { - import ComboBox._ - lazy val ui = new FlowPanel { - contents += new ComboBox(List(1,2,3,4)) - - val patterns = List("dd MMMMM yyyy", - "dd.MM.yy", - "MM/dd/yy", - "yyyy.MM.dd G 'at' hh:mm:ss z", - "EEE, MMM d, ''yy", - "h:mm a", - "H:mm:ss:SSS", - "K:mm a,z", - "yyyy.MMMMM.dd GGG hh:mm aaa") - val dateBox = new ComboBox(patterns) { makeEditable() } - contents += dateBox - val field = new TextField(20) { editable = false } - contents += field - - reactions += { - case SelectionChanged(`dateBox`) => reformat() - } - listenTo(dateBox.selection) - - def reformat() { - try { - val today = new Date - val formatter = new SimpleDateFormat(dateBox.selection.item) - val dateString = formatter.format(today) - field.foreground = Color.black - field.text = dateString - } catch { - case e: IllegalArgumentException => - field.foreground = Color.red - field.text = "Error: " + e.getMessage - } - } - - - val icons = try { - List(new ImageIcon(resourceFromClassloader("images/margarita1.jpg")), - new ImageIcon(resourceFromClassloader("images/margarita2.jpg")), - new ImageIcon(resourceFromClassloader("images/rose.jpg")), - new ImageIcon(resourceFromClassloader("images/banana.jpg"))) - } catch { - case _ => - println("Couldn't load images for combo box") - List(Swing.EmptyIcon) - } - - val iconBox = new ComboBox(icons) { - renderer = new ListView.AbstractRenderer[Icon, Label](new Label) { - def configure(list: ListView[_], isSelected: Boolean, focused: Boolean, icon: Icon, index: Int) { - component.icon = icon - component.xAlignment = Alignment.Center - if(isSelected) { - component.border = Swing.LineBorder(list.selectionBackground, 3) - } else { - component.border = Swing.EmptyBorder(3) - } - } - } - } - contents += iconBox - } - - def top = new MainFrame { - title = "ComboBoxes Demo" - contents = ui - } -} - diff --git a/docs/examples/swing/CountButton.scala b/docs/examples/swing/CountButton.scala deleted file mode 100644 index 5fb14681d6..0000000000 --- a/docs/examples/swing/CountButton.scala +++ /dev/null @@ -1,30 +0,0 @@ -package examples.swing - -import scala.swing._ -import scala.swing.event._ - -object CountButton extends SimpleSwingApplication { - def top = new MainFrame { - title = "My Frame" - contents = new GridPanel(2, 2) { - hGap = 3 - vGap = 3 - val button = new Button { - text = "Press Me!" - } - contents += button - val label = new Label { - text = "No button clicks registered" - } - contents += label - - listenTo(button) - var nclicks = 0 - reactions += { - case ButtonClicked(b) => - nclicks += 1 - label.text = "Number of button clicks: "+nclicks - } - } - } -} diff --git a/docs/examples/swing/Dialogs.scala b/docs/examples/swing/Dialogs.scala deleted file mode 100644 index 0b4ac258cf..0000000000 --- a/docs/examples/swing/Dialogs.scala +++ /dev/null @@ -1,176 +0,0 @@ -package examples.swing - -import swing._ -import swing.event._ - -object Dialogs extends SimpleSwingApplication { - import TabbedPane._ - - lazy val label = new Label("No Result yet") - lazy val tabs = new TabbedPane { - pages += new Page("File", new GridBagPanel { grid => - import GridBagPanel._ - val buttonText = new TextField("Click Me") - - val c = new Constraints - c.fill = Fill.Horizontal - c.grid = (1,1) - - val chooser = new FileChooser - layout(new Button(Action("Open") { - chooser.showOpenDialog(grid) - })) = c - - c.grid = (1,2) - layout(new Button(Action("Save") { - chooser.showSaveDialog(grid) - })) = c - - c.grid = (1,3) - layout(new Button(Action("Custom") { - chooser.showDialog(grid, buttonText.text) - })) = c - - c.grid = (2,3) - layout(new Label(" with Text ")) = c - - c.grid = (3,3) - c.ipadx = 50 - layout(buttonText) = c - - border = Swing.EmptyBorder(5, 5, 5, 5) - }) - pages += new Page("Simple Modal Dialogs", new BorderPanel { - import BorderPanel._ - val mutex = new ButtonGroup - val ok = new RadioButton("OK (in the L&F's words)") - val ynlf = new RadioButton("Yes/No (in the L&F's words)") - val ynp = new RadioButton("Yes/No (in the programmer's words)") - val yncp = new RadioButton("Yes/No/Cancel (in the programmer's words)") - val radios = List(ok, ynlf, ynp, yncp) - mutex.buttons ++= radios - mutex.select(ok) - val buttons = new BoxPanel(Orientation.Vertical) { - contents ++= radios - } - layout(buttons) = Position.North - layout(new Button(Action("Show It!") { - import Dialog._ - mutex.selected.get match { - case `ok` => - showMessage(buttons, "Eggs aren't supposed to be green.") - case `ynlf` => - label.text = showConfirmation(buttons, - "Would you like green eggs and ham?", - "An Inane Question") match { - case Result.Yes => "Ewww!" - case Result.No => "Me neither!" - case _ => "Come on -- tell me!" - } - case `ynp` => - val options = List("Yes, please", - "No, thanks", - "No eggs, no ham!") - label.text = showOptions(buttons, - "Would you like some green eggs to go with that ham?", - "A Silly Question", - entries = options, - initial = 2) match { - case Result.Yes => "You're kidding!" - case Result.No => "I don't like them, either." - case _ => "Come on -- 'fess up!" - } - case `yncp` => - val options = List("Yes, please", - "No, thanks", - "No eggs, no ham!") - label.text = showOptions(buttons, - message = "Would you like some green eggs to go with that ham?", - title = "A Silly Question", - entries = options, - initial = 2) match { - case Result.Yes => "Here you go: green eggs and ham!" - case Result.No => "OK, just the ham, then." - case Result.Cancel => "Well, I'm certainly not going to eat them!" - case _ => "Please tell me what you want!" - } - } - })) = Position.South - }) - pages += new Page("More Dialogs", new BorderPanel { - import BorderPanel._ - val mutex = new ButtonGroup - val pick = new RadioButton("Pick one of several choices") - val enter = new RadioButton("Enter some text") - val custom = new RadioButton("Custom") - val customUndec = new RadioButton("Custom undecorated") - val custom2 = new RadioButton("2 custom dialogs") - val radios = List(pick, enter, custom, customUndec, custom2) - mutex.buttons ++= radios - mutex.select(pick) - val buttons = new BoxPanel(Orientation.Vertical) { - contents ++= radios - } - layout(buttons) = Position.North - layout(new Button(Action("Show It!") { - import Dialog._ - mutex.selected.get match { - case `pick` => - val possibilities = List("ham", "spam", "yam") - val s = showInput(buttons, - "Complete the sentence:\n\"Green eggs and...\"", - "Customized Dialog", - Message.Plain, - Swing.EmptyIcon, - possibilities, "ham") - - //If a string was returned, say so. - label.text = if ((s != None) && (s.get.length > 0)) - "Green eggs and... " + s.get + "!" - else - "Come on, finish the sentence!" - case `enter` => - val s = showInput(buttons, - "Complete the sentence:\n\"Green eggs and...\"", - "Customized Dialog", - Message.Plain, - Swing.EmptyIcon, - Nil, "ham") - - //If a string was returned, say so. - label.text = if ((s != None) && (s.get.length > 0)) - "Green eggs and... " + s.get + "!" - else - "Come on, finish the sentence!" - case `custom` => - val dialog = new Dialog(top) - dialog.open() - dialog.contents = Button("Close Me!") { dialog.close() } - case `customUndec` => - val dialog = new Dialog with RichWindow.Undecorated - dialog.open() - dialog.contents = Button("Close Me!") { dialog.close() } - case `custom2` => - val d1 = new Dialog - val d2 = new Dialog(d1) - d1.open() - d2.open() - d1.contents = Button("Close Me! I am the owner and will automatically close the other one") { d1.close() } - d2.contents = Button("Close Me!") { d2.close() } - } - })) = Position.South - }) - } - - lazy val ui: Panel = new BorderPanel { - layout(tabs) = BorderPanel.Position.Center - layout(label) = BorderPanel.Position.South - } - - - lazy val top = new MainFrame { - title = "Dialog Demo" - contents = ui - } -} - diff --git a/docs/examples/swing/GridBagDemo.scala b/docs/examples/swing/GridBagDemo.scala deleted file mode 100644 index 60cfc13acb..0000000000 --- a/docs/examples/swing/GridBagDemo.scala +++ /dev/null @@ -1,64 +0,0 @@ -package examples.swing - -import swing._ -import swing.event._ -import GridBagPanel._ -import java.awt.Insets - -object GridBagDemo extends SimpleSwingApplication { - lazy val ui = new GridBagPanel { - val c = new Constraints - val shouldFill = true - if (shouldFill) { - c.fill = Fill.Horizontal - } - - val button1 = new Button("Button 1") - - c.weightx = 0.5 - - c.fill = Fill.Horizontal - c.gridx = 0; - c.gridy = 0; - layout(button1) = c - - val button2 = new Button("Button 2") - c.fill = Fill.Horizontal - c.weightx = 0.5; - c.gridx = 1; - c.gridy = 0; - layout(button2) = c - - val button3 = new Button("Button 3") - c.fill = Fill.Horizontal - c.weightx = 0.5; - c.gridx = 2; - c.gridy = 0; - layout(button3) = c - - val button4 = new Button("Long-Named Button 4") - c.fill = Fill.Horizontal - c.ipady = 40; //make this component tall - c.weightx = 0.0; - c.gridwidth = 3; - c.gridx = 0; - c.gridy = 1; - layout(button4) = c - - val button5 = new Button("5") - c.fill = Fill.Horizontal - c.ipady = 0; //reset to default - c.weighty = 1.0; //request any extra vertical space - c.anchor = Anchor.PageEnd - c.insets = new Insets(10,0,0,0); //top padding - c.gridx = 1; //aligned with button 2 - c.gridwidth = 2; //2 columns wide - c.gridy = 2; //third row - layout(button5) = c - } - - def top = new MainFrame { - title = "GridBag Demo" - contents = ui - } -} diff --git a/docs/examples/swing/HelloWorld.scala b/docs/examples/swing/HelloWorld.scala deleted file mode 100644 index e89bfedd8a..0000000000 --- a/docs/examples/swing/HelloWorld.scala +++ /dev/null @@ -1,13 +0,0 @@ -package examples.swing - -import swing._ - -/** - * A simple swing demo. - */ -object HelloWorld extends SimpleSwingApplication { - def top = new MainFrame { - title = "Hello, World!" - contents = new Button("Click Me!") - } -} diff --git a/docs/examples/swing/LabelTest.scala b/docs/examples/swing/LabelTest.scala deleted file mode 100644 index edd7a14634..0000000000 --- a/docs/examples/swing/LabelTest.scala +++ /dev/null @@ -1,19 +0,0 @@ -package examples.swing - -import scala.swing._ -import scala.swing.event._ - -object LabelTest extends SimpleSwingApplication { - def top = new MainFrame{ - contents = new Label { - text = "Hello" - import java.awt.event._ - listenTo(mouse.clicks) - reactions += { - case MousePressed(_,_,_,_,_) => - println("Mouse pressed2") - } - } - } -} - diff --git a/docs/examples/swing/LinePainting.scala b/docs/examples/swing/LinePainting.scala deleted file mode 100644 index f72f8701ed..0000000000 --- a/docs/examples/swing/LinePainting.scala +++ /dev/null @@ -1,53 +0,0 @@ -package examples.swing - -import scala.swing.Swing._ -import scala.swing.{MainFrame, Panel} -import scala.swing.event._ -import java.awt.{Color, Graphics2D, Point, geom} - -/** - * Dragging the mouse draws a simple graph - * - * @author Frank Teubler, Ingo Maier - */ -object LinePainting extends SimpleSwingApplication { - lazy val ui = new Panel { - background = Color.white - preferredSize = (200,200) - - focusable = true - listenTo(mouse.clicks, mouse.moves, keys) - - reactions += { - case e: MousePressed => - moveTo(e.point) - requestFocusInWindow() - case e: MouseDragged => lineTo(e.point) - case e: MouseReleased => lineTo(e.point) - case KeyTyped(_,'c',_,_) => - path = new geom.GeneralPath - repaint() - case _: FocusLost => repaint() - } - - /* records the dragging */ - var path = new geom.GeneralPath - - def lineTo(p: Point) { path.lineTo(p.x, p.y); repaint() } - def moveTo(p: Point) { path.moveTo(p.x, p.y); repaint() } - - override def paintComponent(g: Graphics2D) = { - super.paintComponent(g) - g.setColor(new Color(100,100,100)) - g.drawString("Press left mouse button and drag to paint." + - (if(hasFocus) " Press 'c' to clear." else ""), 10, size.height-10) - g.setColor(Color.black) - g.draw(path) - } - } - - def top = new MainFrame { - title = "Simple Line Painting Demo" - contents = ui - } -} diff --git a/docs/examples/swing/ListViewDemo.scala b/docs/examples/swing/ListViewDemo.scala deleted file mode 100644 index 5630f2871d..0000000000 --- a/docs/examples/swing/ListViewDemo.scala +++ /dev/null @@ -1,17 +0,0 @@ -package examples.swing - -object ListViewDemo extends SimpleSwingApplication { - def top = new MainFrame { - case class City(name: String, country: String, population: Int, capital: Boolean) - val items = List(City("Lausanne", "Switzerland", 129273, false), - City("Paris", "France", 2203817, true), - City("New York", "USA", 8363710 , false), - City("Berlin", "Germany", 3416300, true), - City("Tokio", "Japan", 12787981, true)) - import ListView._ - contents = new FlowPanel(new ScrollPane(new ListView(items) { - renderer = Renderer(_.name) - })) - //new ScrollPane(new Table(items))) - } -} diff --git a/docs/examples/swing/SimpleApplet.scala b/docs/examples/swing/SimpleApplet.scala deleted file mode 100644 index 502de537a3..0000000000 --- a/docs/examples/swing/SimpleApplet.scala +++ /dev/null @@ -1,18 +0,0 @@ -package examples.swing - -import event._ - -class SimpleApplet extends Applet { - object ui extends UI with Reactor { - def init() = { - val button = new Button("Press here!") - val text = new TextArea("Java Version: " + util.Properties.javaVersion + "\n") - listenTo(button) - reactions += { - case ButtonClicked(_) => text.text += "Button Pressed!\n" - case _ => - } - contents = new BoxPanel(Orientation.Vertical) { contents.append(button, text) } - } - } -} diff --git a/docs/examples/swing/SwingApp.scala b/docs/examples/swing/SwingApp.scala deleted file mode 100644 index b3fe7447ef..0000000000 --- a/docs/examples/swing/SwingApp.scala +++ /dev/null @@ -1,29 +0,0 @@ -package examples.swing - -import swing._ -import swing.event._ - -object SwingApp extends SimpleSwingApplication { - def top = new MainFrame { - title = "SwingApp" - var numclicks = 0 - object label extends Label { - val prefix = "Number of button clicks: " - text = prefix + "0 " - listenTo(button) - reactions += { - case ButtonClicked(button) => - numclicks = numclicks + 1 - text = prefix + numclicks - } - } - object button extends Button { - text = "I am a button" - } - contents = new FlowPanel { - contents.append(button, label) - border = Swing.EmptyBorder(5, 5, 5, 5) - } - } -} - diff --git a/docs/examples/swing/TableSelection.scala b/docs/examples/swing/TableSelection.scala deleted file mode 100644 index 8c8ea4ffcc..0000000000 --- a/docs/examples/swing/TableSelection.scala +++ /dev/null @@ -1,96 +0,0 @@ -package examples.swing - -import java.awt.Dimension -import swing.event._ - -object TableSelection extends SimpleSwingApplication { - val model = Array(List("Mary", "Campione", "Snowboarding", 5, false).toArray, - List("Alison", "Huml", "Rowing", 5, false).toArray, - List("Kathy", "Walrath", "Knitting", 5, false).toArray, - List("Sharon", "Zakhour", "Speed reading", 5, false).toArray, - List("Philip", "Milne", "Pool", 5, false).toArray) - /*val model = Array.tabulate(10000) { i => - List("Mary", "Campione", "Snowboarding", i, false).toArray - }*/ - - lazy val ui = new BoxPanel(Orientation.Vertical) { - val table = new Table(model, Array("First Name", "Last Name", "Sport", "# of Years", "Vegetarian")) { - preferredViewportSize = new Dimension(500, 70) - } - //1.6:table.fillsViewportHeight = true - listenTo(table.selection) - - contents += new ScrollPane(table) - contents += new Label("Selection Mode") - - def radio(mutex: ButtonGroup, text: String): RadioButton = { - val b = new RadioButton(text) - listenTo(b) - mutex.buttons += b - contents += b - b - } - - val intervalMutex = new ButtonGroup - val multiInterval = radio(intervalMutex, "Multiple Interval Selection") - val elementInterval = radio(intervalMutex, "Single Selection") - val singleInterval = radio(intervalMutex, "Single Interval Selection") - intervalMutex.select(multiInterval) - - contents += new Label("Selection Options") - val elemMutex = new ButtonGroup - val rowSelection = radio(elemMutex, "Row Selection") - val columnSelection = radio(elemMutex, "Column Selection") - val cellSelection = radio(elemMutex, "Cell Selection") - elemMutex.select(rowSelection) - - val output = new TextArea(5, 40) { editable = false } - contents += new ScrollPane(output) - - def outputSelection() { - output.append("Lead: " + table.selection.rows.leadIndex + "," + - table.selection.columns.leadIndex + ". ") - output.append("Rows:") - for (c <- table.selection.rows) output.append(" " + c) - output.append(". Columns:") - for (c <- table.selection.columns) output.append(" " + c) - output.append(".\n") - } - - reactions += { - case ButtonClicked(`multiInterval`) => - table.selection.intervalMode = Table.IntervalMode.MultiInterval - if (cellSelection.selected) { - elemMutex.select(rowSelection) - table.selection.elementMode = Table.ElementMode.None - } - cellSelection.enabled = false - case ButtonClicked(`elementInterval`) => - table.selection.intervalMode = Table.IntervalMode.Single - cellSelection.enabled = true - case ButtonClicked(`singleInterval`) => - table.selection.intervalMode = Table.IntervalMode.SingleInterval - cellSelection.enabled = true - case ButtonClicked(`rowSelection`) => - if (rowSelection.selected) - table.selection.elementMode = Table.ElementMode.Row - case ButtonClicked(`columnSelection`) => - if (columnSelection.selected) - table.selection.elementMode = Table.ElementMode.Column - case ButtonClicked(`cellSelection`) => - if (cellSelection.selected) - table.selection.elementMode = Table.ElementMode.Cell - case TableRowsSelected(_, range, false) => - output.append("Rows selected, changes: " + range + "\n") - outputSelection() - case TableColumnsSelected(_, range, false) => - output.append("Columns selected, changes " + range + "\n") - outputSelection() - } - } - - def top = new MainFrame { - title = "Table Selection" - contents = ui - } -} diff --git a/docs/examples/swing/UIDemo.scala b/docs/examples/swing/UIDemo.scala deleted file mode 100644 index 6d77c049e0..0000000000 --- a/docs/examples/swing/UIDemo.scala +++ /dev/null @@ -1,147 +0,0 @@ -package examples.swing - -import swing._ -import event._ -import Swing._ -import ListView._ - -object UIDemo extends SimpleSwingApplication { - def top = new MainFrame { - title = "Scala Swing Demo" - - /* - * Create a menu bar with a couple of menus and menu items and - * set the result as this frame's menu bar. - */ - menuBar = new MenuBar { - contents += new Menu("A Menu") { - contents += new MenuItem("An item") - contents += new MenuItem(Action("An action item") { - println("Action '"+ title +"' invoked") - }) - contents += new Separator - contents += new CheckMenuItem("Check me") - contents += new CheckMenuItem("Me too!") - contents += new Separator - val a = new RadioMenuItem("a") - val b = new RadioMenuItem("b") - val c = new RadioMenuItem("c") - val mutex = new ButtonGroup(a,b,c) - contents ++= mutex.buttons - } - contents += new Menu("Empty Menu") - } - - /* - * The root component in this frame is a panel with a border layout. - */ - contents = new BorderPanel { - import BorderPanel.Position._ - - var reactLive = false - - val tabs = new TabbedPane { - import TabbedPane._ - val buttons = new FlowPanel { - border = Swing.EmptyBorder(5,5,5,5) - - contents += new BoxPanel(Orientation.Vertical) { - border = CompoundBorder(TitledBorder(EtchedBorder, "Radio Buttons"), EmptyBorder(5,5,5,10)) - val a = new RadioButton("Green Vegetables") - val b = new RadioButton("Red Meat") - val c = new RadioButton("White Tofu") - val mutex = new ButtonGroup(a,b,c) - contents ++= mutex.buttons - } - contents += new BoxPanel(Orientation.Vertical) { - border = CompoundBorder(TitledBorder(EtchedBorder, "Check Boxes"), EmptyBorder(5,5,5,10)) - val paintLabels = new CheckBox("Paint Labels") - val paintTicks = new CheckBox("Paint Ticks") - val snapTicks = new CheckBox("Snap To Ticks") - val live = new CheckBox("Live") - contents.append(paintLabels, paintTicks, snapTicks, live) - listenTo(paintLabels, paintTicks, snapTicks, live) - reactions += { - case ButtonClicked(`paintLabels`) => - slider.paintLabels = paintLabels.selected - case ButtonClicked(`paintTicks`) => - slider.paintTicks = paintTicks.selected - case ButtonClicked(`snapTicks`) => - slider.snapToTicks = snapTicks.selected - case ButtonClicked(`live`) => - reactLive = live.selected - } - } - contents += new Button(Action("Center Frame") { centerOnScreen() }) - } - pages += new Page("Buttons", buttons) - pages += new Page("GridBag", GridBagDemo.ui) - pages += new Page("Converter", CelsiusConverter2.ui) - pages += new Page("Tables", TableSelection.ui) - pages += new Page("Dialogs", Dialogs.ui) - pages += new Page("Combo Boxes", ComboBoxes.ui) - pages += new Page("Split Panes", - new SplitPane(Orientation.Vertical, new Button("Hello"), new Button("World")) { - continuousLayout = true - }) - - val password = new FlowPanel { - contents += new Label("Enter your secret password here ") - val field = new PasswordField(10) - contents += field - val label = new Label(field.text) - contents += label - listenTo(field) - reactions += { - case EditDone(`field`) => label.text = field.password.mkString - } - } - - pages += new Page("Password", password) - pages += new Page("Painting", LinePainting.ui) - //pages += new Page("Text Editor", TextEditor.ui) - } - - val list = new ListView(tabs.pages) { - selectIndices(0) - selection.intervalMode = ListView.IntervalMode.Single - renderer = ListView.Renderer(_.title) - } - val center = new SplitPane(Orientation.Vertical, new ScrollPane(list), tabs) { - oneTouchExpandable = true - continuousLayout = true - } - layout(center) = Center - - /* - * This slider is used above, so we need lazy initialization semantics. - * Objects or lazy vals are the way to go, but objects give us better - * type inference at times. - */ - object slider extends Slider { - min = 0 - value = tabs.selection.index - max = tabs.pages.size-1 - majorTickSpacing = 1 - } - layout(slider) = South - - /* - * Establish connection between the tab pane, slider, and list view. - */ - listenTo(slider) - listenTo(tabs.selection) - listenTo(list.selection) - reactions += { - case ValueChanged(`slider`) => - if(!slider.adjusting || reactLive) tabs.selection.index = slider.value - case SelectionChanged(`tabs`) => - slider.value = tabs.selection.index - list.selectIndices(tabs.selection.index) - case SelectionChanged(`list`) => - if (list.selection.items.length == 1) - tabs.selection.page = list.selection.items(0) - } - } - } -} diff --git a/docs/examples/swing/images/banana.jpg b/docs/examples/swing/images/banana.jpg Binary files differdeleted file mode 100644 index 62267a4325..0000000000 --- a/docs/examples/swing/images/banana.jpg +++ /dev/null diff --git a/docs/examples/swing/images/margarita1.jpg b/docs/examples/swing/images/margarita1.jpg Binary files differdeleted file mode 100644 index d315f7c79f..0000000000 --- a/docs/examples/swing/images/margarita1.jpg +++ /dev/null diff --git a/docs/examples/swing/images/margarita2.jpg b/docs/examples/swing/images/margarita2.jpg Binary files differdeleted file mode 100644 index c8b076e5f9..0000000000 --- a/docs/examples/swing/images/margarita2.jpg +++ /dev/null diff --git a/docs/examples/swing/images/rose.jpg b/docs/examples/swing/images/rose.jpg Binary files differdeleted file mode 100644 index d4a2b58062..0000000000 --- a/docs/examples/swing/images/rose.jpg +++ /dev/null diff --git a/docs/examples/tcpoly/collection/HOSeq.scala b/docs/examples/tcpoly/collection/HOSeq.scala deleted file mode 100644 index a6757b95ba..0000000000 --- a/docs/examples/tcpoly/collection/HOSeq.scala +++ /dev/null @@ -1,167 +0,0 @@ -package examples.tcpoly.collection; - -trait HOSeq { - // an internal interface that encapsulates the accumulation of elements (of type elT) to produce - // a structure of type coll[elT] -- different kinds of collections should provide different implicit - // values implementing this interface, in order to provide more performant ways of building that structure - trait Accumulator[+coll[x], elT] { - def += (el: elT): Unit - def result: coll[elT] - } - - - // Iterable abstracts over the type of its structure as well as its elements (see PolyP's Bifunctor) - // m[x] is intentionally unbounded: fold can then be defined nicely - // variance: if we write m[+x] instead of +m[+x], x is an invariant position because its enclosing type - // is an invariant position -- should probably rule that out? - trait Iterable[+m[+x], +t] { - //def unit[a](orig: a): m[a] - def iterator: Iterator[t] - - // construct an empty accumulator that will produce the same structure as this iterable, with elements of type t - def accumulator[t]: Accumulator[m, t] - - def filter(p: t => Boolean): m[t] = { - val buf = accumulator[t] - val elems = elements - while (elems.hasNext) { val x = elems.next; if (p(x)) buf += x } - buf.result - } - - def map[s](f: t => s): m[s] = { - val buf = accumulator[s] - val elems = elements - while (elems.hasNext) buf += f(elems.next) - buf.result - } - - // flatMap is a more specialized map, it only works if the mapped function produces Iterable values, - // which are then added to the result one by one - // the compiler should be able to find the right accumulator (implicit buf) to build the result - // to get concat, resColl = SingletonIterable, f = unit for SingletonIterable - def flatMap[resColl[x] <: Iterable[resColl, x], s](f: t => resColl[s])(implicit buf: Accumulator[resColl, s]): resColl[s] = { - // TODO: would a viewbound for resColl[x] be better? - // -- 2nd-order type params are not yet in scope in view bound - val elems = elements - while (elems.hasNext) { - val elemss: Iterator[s] = f(elems.next).iterator - while (elemss.hasNext) buf += elemss.next - } - buf.result - } - } - - final class ListBuffer[A] { - private var start: List[A] = Nil - private var last: ::[A] = _ - private var exported: boolean = false - - /** Appends a single element to this buffer. - * - * @param x the element to append. - */ - def += (x: A): unit = { - if (exported) copy - if (start.isEmpty) { - last = new HOSeq.this.:: (x, Nil) - start = last - } else { - val last1 = last - last = new HOSeq.this.:: (x, null) // hack: ::'s tail will actually be last - //last1.tl = last - } - } - - /** Converts this buffer to a list - */ - def toList: List[A] = { - exported = !start.isEmpty - start - } - - /** Clears the buffer contents. - */ - def clear: unit = { - start = Nil - exported = false - } - - /** Copy contents of this buffer */ - private def copy = { - var cursor = start - val limit = last.tail - clear - while (cursor ne limit) { - this += cursor.head - cursor = cursor.tail - } - } - } - - implicit def listAccumulator[elT]: Accumulator[List, elT] = new Accumulator[List, elT] { - private[this] val buff = new ListBuffer[elT] - def += (el: elT): Unit = buff += el - def result: List[elT] = buff.toList - } - - trait List[+t] extends Iterable[List, t] { - def head: t - def tail: List[t] - def isEmpty: Boolean - def iterator: Iterator[t] = error("TODO") - - // construct an empty accumulator that will produce the same structure as this iterable, with elements of type t - def accumulator[t]: Accumulator[List, t] = error("TODO") - } - - // TODO: the var tl approach does not seem to work because subtyping isn't fully working yet - final case class ::[+b](hd: b, private val tl: List[b]) extends List[b] { - def head = hd - def tail = if(tl==null) this else tl // hack - override def isEmpty: boolean = false - } - - case object Nil extends List[Nothing] { - def isEmpty = true - def head: Nothing = - throw new NoSuchElementException("head of empty list") - def tail: List[Nothing] = - throw new NoSuchElementException("tail of empty list") - } -} - - - -// misc signatures collected from mailing list / library code: - /*override def flatMap[B](f: A => Iterable[B]): Set[B] - final override def flatMap[b](f: Any => Iterable[b]): Array[b] - def flatMap[b](f: a => Parser[b]) = new Parser[b] - override def flatMap[b](f: a => Iterable[b]): List[b] - - - MapResult[K] <: Seq[K] - FilterResult <: Seq[T] - Concat <: Seq[T] - Subseq <: Seq[T] - - - def map[K](f: T=>K): MapResult[K] - def filter(f: T=>Boolean): FilterResult - def subseq(from: int, to: int): Subseq - def flatMap[S <: Seq[K], K](f: T => S): S#Concat // legal? - def concat(others: Seq[T]): Concat - */ - -/*trait Iterator[t] { - // @post hasAdvanced implies hasNext - // model def hasAdvanced: Boolean - - def hasNext: Boolean // pure - - // @pre hasAdvanced - def current: t // pure - - // @pre hasNext - // @post hasAdvanced - def advance: Unit -}*/ diff --git a/docs/examples/tcpoly/monads/Monads.scala b/docs/examples/tcpoly/monads/Monads.scala deleted file mode 100644 index b6e3d5b9a8..0000000000 --- a/docs/examples/tcpoly/monads/Monads.scala +++ /dev/null @@ -1,69 +0,0 @@ -package examples.tcpoly.monad; - -trait Monads { - /** - * class Monad m where - * (>>=) :: m a -> (a -> m b) -> m b - * return :: a -> m a - * - * MonadTC encodes the above Haskell type class, - * an instance of MonadTC corresponds to a method dictionary. - * (see http://lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf) - * - * Note that the identity (`this') of the method dictionary does not really correspond - * to the instance of m[x] (`self') that is `wrapped': e.g., unit does not use `self' (which - * corresponds to the argument of the implicit conversion that encodes an instance of this type class) - */ - // Option =:= [x] => Option[x] <: [x] => Any -// trait MonadTC[m <: [x] => Any, a] { - // MonadTC[m[x], a] x is a type parameter too -- should not write e.g., m[Int] here - trait MonadTC[m[x], a] { - def unit[a](orig: a): m[a] - - // >>='s first argument comes from the implicit definition constructing this "method dictionary" - def >>=[b](fun: a => m[b]): m[b] - } -} - -/** - * instance Monad Maybe where - * (Just x) >>= k = k x - * Nothing >>= _ = Nothing - */ -trait OptionMonad extends Monads { - // this implicit method encodes the Monad type class instance for Option - implicit def OptionInstOfMonad[a](self: Option[a]): MonadTC[Option, a] - = new MonadTC[Option, a] { - def unit[a](orig: a) = Some(orig) - def >>=[b](fun: a => Option[b]): Option[b] = self match { - case Some(x) => fun(x) - case None => None - } - } -} - -object main extends OptionMonad with Application { - Console.println(Some("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") >>= (x => Some(x.length))) -} - - -/* -trait MonadTC[m[x], a] requires m[x] { - def unit[a](orig: a): m[a] - - // >>='s first argument comes from the implicit definition constructing this "method dictionary" - def >>=[b](fun: a => m[b]): m[b] -} - -abstract class OptionIsMonad[t[x] <: Option[x], a] implicit extends MonadTC[t, a] { - def unit[a](orig: a) = Some(orig) // TODO: problematic.. is a meta-member: not invoked on this -} - -class SomeIsMonad[a] extends OptionIsMonad[Some, a] { - def >>=[b](fun: a => Option[b]): Option[b] = fun(x) -} - -class NoneIsMonad[a] extends OptionIsMonad[None, a] { - def >>=[b](fun: a => Option[b]): Option[b] = None -} -*/ diff --git a/docs/examples/typeinf.scala b/docs/examples/typeinf.scala deleted file mode 100644 index ac6cc35f6b..0000000000 --- a/docs/examples/typeinf.scala +++ /dev/null @@ -1,253 +0,0 @@ -package examples - -object typeinf { - -trait Term {} - -case class Var(x: String) extends Term { - override def toString() = x -} -case class Lam(x: String, e: Term) extends Term { - override def toString() = "(\\" + x + "." + e + ")" -} -case class App(f: Term, e: Term) extends Term { - override def toString() = "(" + f + " " + e + ")" -} -case class Let(x: String, e: Term, f: Term) extends Term { - override def toString() = "let " + x + " = " + e + " in " + f -} - -sealed trait Type {} -case class Tyvar(a: String) extends Type { - override def toString() = a -} -case class Arrow(t1: Type, t2: Type) extends Type { - override def toString() = "(" + t1 + "->" + t2 + ")" -} -case class Tycon(k: String, ts: List[Type]) extends Type { - override def toString() = - k + (if (ts.isEmpty) "" else ts.mkString("[", ",", "]")) -} - -object typeInfer { - - private var n: Int = 0 - def newTyvar(): Type = { n += 1; Tyvar("a" + n) } - - trait Subst extends Function1[Type, Type] { - def lookup(x: Tyvar): Type - def apply(t: Type): Type = t match { - case tv @ Tyvar(a) => val u = lookup(tv); if (t == u) t else apply(u) - case Arrow(t1, t2) => Arrow(apply(t1), apply(t2)) - case Tycon(k, ts) => Tycon(k, ts map apply) - } - def extend(x: Tyvar, t: Type) = new Subst { - def lookup(y: Tyvar): Type = if (x == y) t else Subst.this.lookup(y) - } - } - - val emptySubst = new Subst { def lookup(t: Tyvar): Type = t } - - case class TypeScheme(tyvars: List[Tyvar], tpe: Type) { - def newInstance: Type = - (emptySubst /: tyvars) ((s, tv) => s.extend(tv, newTyvar())) (tpe) - } - - type Env = List[Tuple2[String, TypeScheme]] - - def lookup(env: Env, x: String): TypeScheme = env match { - case List() => null - case (y, t) :: env1 => if (x == y) t else lookup(env1, x) - } - - def gen(env: Env, t: Type): TypeScheme = - TypeScheme(tyvars(t) diff tyvars(env), t) - - def tyvars(t: Type): List[Tyvar] = t match { - case tv @ Tyvar(a) => List(tv) - case Arrow(t1, t2) => tyvars(t1) union tyvars(t2) - case Tycon(k, ts) => (List[Tyvar]() /: ts) ((tvs, t) => tvs union tyvars(t)) - } - - def tyvars(ts: TypeScheme): List[Tyvar] = - tyvars(ts.tpe) diff ts.tyvars; - - def tyvars(env: Env): List[Tyvar] = - (List[Tyvar]() /: env) ((tvs, nt) => tvs union tyvars(nt._2)) - - def mgu(t: Type, u: Type, s: Subst): Subst = (s(t), s(u)) match { - case (Tyvar(a), Tyvar(b)) if (a == b) => - s - case (Tyvar(a), _) if !(tyvars(u) contains a) => - s.extend(Tyvar(a), u) - case (_, Tyvar(a)) => - mgu(u, t, s) - case (Arrow(t1, t2), Arrow(u1, u2)) => - mgu(t1, u1, mgu(t2, u2, s)) - case (Tycon(k1, ts), Tycon(k2, us)) if (k1 == k2) => - (s /: (ts zip us)) ((s, tu) => mgu(tu._1, tu._2, s)) - case _ => - throw new TypeError("cannot unify " + s(t) + " with " + s(u)) - } - - case class TypeError(s: String) extends Exception(s) {} - - def tp(env: Env, e: Term, t: Type, s: Subst): Subst = { - current = e - e match { - case Var(x) => - val u = lookup(env, x) - if (u == null) throw new TypeError("undefined: " + x) - else mgu(u.newInstance, t, s) - - case Lam(x, e1) => - val a, b = newTyvar() - val s1 = mgu(t, Arrow(a, b), s) - val env1 = (x, TypeScheme(List(), a)) :: env - tp(env1, e1, b, s1) - - case App(e1, e2) => - val a = newTyvar() - val s1 = tp(env, e1, Arrow(a, t), s) - tp(env, e2, a, s1) - - case Let(x, e1, e2) => - val a = newTyvar() - val s1 = tp(env, e1, a, s) - tp((x, gen(env, s1(a))) :: env, e2, t, s1) - } - } - var current: Term = null - - def typeOf(env: Env, e: Term): Type = { - val a = newTyvar() - tp(env, e, a, emptySubst)(a) - } -} - - object predefined { - val booleanType = Tycon("Boolean", List()) - val intType = Tycon("Int", List()) - def listType(t: Type) = Tycon("List", List(t)) - - private def gen(t: Type): typeInfer.TypeScheme = typeInfer.gen(List(), t) - private val a = typeInfer.newTyvar() - val env = List( -/* - ("true", gen(booleanType)), - ("false", gen(booleanType)), - ("if", gen(Arrow(booleanType, Arrow(a, Arrow(a, a))))), - ("zero", gen(intType)), - ("succ", gen(Arrow(intType, intType))), - ("nil", gen(listType(a))), - ("cons", gen(Arrow(a, Arrow(listType(a), listType(a))))), - ("isEmpty", gen(Arrow(listType(a), booleanType))), - ("head", gen(Arrow(listType(a), a))), - ("tail", gen(Arrow(listType(a), listType(a)))), -*/ - ("fix", gen(Arrow(Arrow(a, a), a))) - ) - } - - trait MiniMLParsers extends CharParsers { - - /** whitespace */ - def whitespace = rep{chr(' ') ||| chr('\t') ||| chr('\n')} - - /** A given character, possible preceded by whitespace */ - def wschr(ch: char) = whitespace &&& chr(ch) - - def isLetter = (c: char) => Character.isLetter(c) - def isLetterOrDigit: char => boolean = Character.isLetterOrDigit - - /** identifiers or keywords */ - def id: Parser[String] = - for ( - c: char <- rep(chr(' ')) &&& chr(isLetter); - cs: List[char] <- rep(chr(isLetterOrDigit)) - ) yield (c :: cs).mkString("", "", "") - - /** Non-keyword identifiers */ - def ident: Parser[String] = - for (s <- id if s != "let" && s != "in") yield s - - /** term = '\' ident '.' term | term1 {term1} | let ident "=" term in term */ - def term: Parser[Term] = ( - ( for ( - _ <- wschr('\\'); - x <- ident; - _ <- wschr('.'); - t <- term) - yield Lam(x, t): Term ) - ||| - ( for ( - letid <- id if letid == "let"; - x <- ident; - _ <- wschr('='); - t <- term; - inid <- id; if inid == "in"; - c <- term) - yield Let(x, t, c) ) - ||| - ( for ( - t <- term1; - ts <- rep(term1)) - yield (t /: ts)((f, arg) => App(f, arg)) ) - ) - - /** term1 = ident | '(' term ')' */ - def term1: Parser[Term] = ( - ( for (s <- ident) - yield Var(s): Term ) - ||| - ( for ( - _ <- wschr('('); - t <- term; - _ <- wschr(')')) - yield t ) - ) - - /** all = term ';' */ - def all: Parser[Term] = - for ( - t <- term; - _ <- wschr(';')) - yield t - } - - class ParseString(s: String) extends Parsers { - type inputType = int - val input = 0 - def any = new Parser[char] { - def apply(in: int): Parser[char]#Result = - if (in < s.length()) Some((s charAt in, in + 1)) else None - } - } - - def showType(e: Term): String = - try { - typeInfer.typeOf(predefined.env, e).toString() - } - catch { - case typeInfer.TypeError(msg) => - "\n cannot type: " + typeInfer.current + - "\n reason: " + msg - } - - def main(args: Array[String]) { - Console.println( - if (args.length == 1) { - val ps = new ParseString(args(0)) with MiniMLParsers - ps.all(ps.input) match { - case Some((term, _)) => - "" + term + ": " + showType(term) - case None => - "syntax error" - } - } - else - "usage: java examples.typeinf <expr-string>" - ) - } - -} diff --git a/docs/examples/xml/phonebook/embeddedBook.scala b/docs/examples/xml/phonebook/embeddedBook.scala deleted file mode 100644 index 3286485f0b..0000000000 --- a/docs/examples/xml/phonebook/embeddedBook.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* examples/phonebook/embeddedBook.scala */ -package phonebook - -object embeddedBook { - - val company = <a href="http://acme.org">ACME</a> - val first = "Burak" - val last = "Emir" - val location = "work" - - val embBook = - <phonebook> - <descr> - This is the <b>phonebook</b> of the - {company} corporation. - </descr> - <entry> - <name>{ first+" "+last }</name> - <phone where={ location }>+41 21 693 68 {val x = 60 + 7; x}</phone> - </entry> - </phonebook>; - - def main(args: Array[String]) = - Console.println( embBook ) - -} diff --git a/docs/examples/xml/phonebook/phonebook.scala b/docs/examples/xml/phonebook/phonebook.scala deleted file mode 100644 index 3c0dfbd837..0000000000 --- a/docs/examples/xml/phonebook/phonebook.scala +++ /dev/null @@ -1,38 +0,0 @@ -package phonebook ; - -object phonebook { - - val labPhoneBook = - <phonebook> - <descr> - This is the <b>phonebook</b> of the - <a href="http://acme.org">ACME</a> corporation. - </descr> - <entry> - <name>Burak</name> - <phone where="work"> +41 21 693 68 67</phone> - <phone where="mobile">+41 79 602 23 23</phone> - </entry> - </phonebook>; - - Console.println( labPhoneBook ); - - // XML is immutable - adding an element - - import scala.xml.{ Node, Text }; - - def add( phonebook:Node, newEntry:Node ):Node = phonebook match { - case <phonebook>{ ch @ _* }</phonebook> => - <phonebook>{ ch }{ newEntry }</phonebook> - } - - val pb2 = - add( labPhoneBook, - <entry> - <name>Kim</name> - <phone where="work"> +41 21 111 11 11</phone> - </entry> ); - - def main(args:Array[String]) = Console.println( pb2 ); - -} diff --git a/docs/examples/xml/phonebook/phonebook1.scala b/docs/examples/xml/phonebook/phonebook1.scala deleted file mode 100644 index 316c6c1995..0000000000 --- a/docs/examples/xml/phonebook/phonebook1.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* examples/phonebook/phonebook1.scala */ -package phonebook - -object phonebook1 { - - val labPhoneBook = - <phonebook> - <descr> - This is the <b>phonebook</b> of the - <a href="http://acme.org">ACME</a> corporation. - </descr> - <entry> - <name>Burak Emir</name> - <phone where="work">+41 21 693 68 67</phone> - </entry> - </phonebook>; - - def main(args: Array[String]) = - Console.println( labPhoneBook ) - -} diff --git a/docs/examples/xml/phonebook/phonebook2.scala b/docs/examples/xml/phonebook/phonebook2.scala deleted file mode 100644 index 2a708daf7c..0000000000 --- a/docs/examples/xml/phonebook/phonebook2.scala +++ /dev/null @@ -1,25 +0,0 @@ -/* examples/xml/phonebook/phonebook2.scala */ -package phonebook; - -object phonebook2 { - - import scala.xml.Node - - /** adds an entry to a phonebook */ - def add( p: Node, newEntry: Node ): Node = p match { - - case <phonebook>{ ch @ _* }</phonebook> => - - <phonebook>{ ch }{ newEntry }</phonebook> - } - - val pb2 = - add( phonebook1.labPhoneBook, - <entry> - <name>Kim</name> - <phone where="work">+41 21 111 11 11</phone> - </entry> ); - - def main( args: Array[String] ) = - Console.println( pb2 ) -} diff --git a/docs/examples/xml/phonebook/phonebook3.scala b/docs/examples/xml/phonebook/phonebook3.scala deleted file mode 100644 index 12f2deaa79..0000000000 --- a/docs/examples/xml/phonebook/phonebook3.scala +++ /dev/null @@ -1,81 +0,0 @@ -package phonebook; - -object phonebook3 { - - import scala.xml.{Elem, Node, Text} ; - import scala.xml.PrettyPrinter ; - import Node.NoAttributes ; - - /* this method "changes" (returns an updated copy) of the phonebook when the - * entry for Name exists. If it has an attribute "where" whose value is equal to the - * parameter Where, it is changed, otherwise, it is added. - */ - def change ( phonebook:Node, Name:String, Where:String, newPhone:String ) = { - - /** this nested function walks through tree, and returns an updated copy of it */ - def copyOrChange ( ch: Iterator[Node] ) = { - - import xml.Utility.{trim,trimProper} //removes whitespace nodes, which are annoying in matches - - for( val c <- ch ) yield - trimProper(c) match { - - // if the node is the particular entry we are looking for, return an updated copy - - case x @ <entry><name>{ Text(Name) }</name>{ ch1 @ _* }</entry> => - - var updated = false; - val ch2 = for(c <- ch1) yield c match { // does it have the phone number? - - case y @ <phone>{ _* }</phone> if y \ "@where" == Where => - updated = true - <phone where={ Where }>{ newPhone }</phone> - - case y => y - - } - if( !updated ) { // no, so we add as first entry - - <entry> - <name>{ Name }</name> - <phone where={ Where }>{ newPhone }</phone> - { ch1 } - </entry> - - } else { // yes, and we changed it as we should - - <entry> - { ch2 } - </entry> - - } - // end case x @ <entry>... - - // other entries are copied without changing them - - case x => - x - - } - } ; // for ... yield ... returns an Iterator[Node] - - // decompose phonebook, apply updates - phonebook match { - case <phonebook>{ ch @ _* }</phonebook> => - <phonebook>{ copyOrChange( ch.iterator ) }</phonebook> - } - - } - - val pb2 = - change( phonebook1.labPhoneBook, "John", "work", "+41 55 555 55 55" ); - - val pp = new PrettyPrinter( 80, 5 ); - - def main( args:Array[String] ) = { - Console.println("---before---"); - Console.println( pp.format( phonebook1.labPhoneBook )); - Console.println("---after---"); - Console.println( pp.format( pb2 )); - } -} diff --git a/docs/examples/xml/phonebook/verboseBook.scala b/docs/examples/xml/phonebook/verboseBook.scala deleted file mode 100644 index 2dcb155480..0000000000 --- a/docs/examples/xml/phonebook/verboseBook.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* examples/xml/phonebook/verboseBook.scala */ -package phonebook - -object verboseBook { - - import scala.xml.{ UnprefixedAttribute, Elem, Node, Null, Text, TopScope } - - val pbookVerbose = - Elem(null, "phonebook", Null, TopScope, - Elem(null, "descr", Null, TopScope, - Text("This is a "), - Elem(null, "b", Null, TopScope, Text("sample")), - Text("description") - ), - Elem(null, "entry", Null, TopScope, - Elem(null, "name", Null, TopScope, Text("Burak Emir")), - Elem(null, "phone", new UnprefixedAttribute("where","work", Null), TopScope, - Text("+41 21 693 68 67")) - ) - ) - - def main(args: Array[String]) = - Console.println( pbookVerbose ) -} diff --git a/docs/licenses/apache_android.txt b/docs/licenses/apache_android.txt deleted file mode 100644 index 00f339625f..0000000000 --- a/docs/licenses/apache_android.txt +++ /dev/null @@ -1,16 +0,0 @@ -Scala includes various example files for Android: - -Copyright (c) 2005-2009, The Android Open Source Project -Copyright (c) 2007, Steven Osborn - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License.
\ No newline at end of file diff --git a/docs/licenses/apache_ant.txt b/docs/licenses/apache_ant.txt deleted file mode 100644 index ac637d760d..0000000000 --- a/docs/licenses/apache_ant.txt +++ /dev/null @@ -1,16 +0,0 @@ -Scala includes Ant as a library needed for build with sbt - -Copyright © 1999-2010, The Apache Software Foundation. - http://ant.apache.org/ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/docs/licenses/apache_jansi.txt b/docs/licenses/apache_jansi.txt new file mode 100644 index 0000000000..067a5a6a34 --- /dev/null +++ b/docs/licenses/apache_jansi.txt @@ -0,0 +1,203 @@ +Scala includes the JLine library, which includes the Jansi library. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/docs/licenses/bsd_asm.txt b/docs/licenses/bsd_asm.txt new file mode 100644 index 0000000000..8613cd33a2 --- /dev/null +++ b/docs/licenses/bsd_asm.txt @@ -0,0 +1,31 @@ +Scala includes the ASM library. + +Copyright (c) 2000-2011 INRIA, France Telecom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file diff --git a/docs/licenses/bsd_jline.txt b/docs/licenses/bsd_jline.txt index 4ac4a378ed..3e5dba75da 100644 --- a/docs/licenses/bsd_jline.txt +++ b/docs/licenses/bsd_jline.txt @@ -1,4 +1,4 @@ -Scala includes the jLine library: +Scala includes the JLine library: Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu> All rights reserved. diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala index 0a56aa45e3..5936b52890 100644 --- a/src/compiler/scala/reflect/macros/compiler/Validators.scala +++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala @@ -155,7 +155,7 @@ trait Validators { else mmap(macroDdef.vparamss)(param) val macroDefRet = if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe - else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef) + else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef) orElse AnyTpe val implReturnType = sigma(increaseMetalevel(ctxPrefix, macroDefRet)) object SigmaTypeMap extends TypeMap { diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala index ff03696524..bddc42d1f9 100644 --- a/src/compiler/scala/reflect/macros/util/Helpers.scala +++ b/src/compiler/scala/reflect/macros/util/Helpers.scala @@ -77,7 +77,8 @@ trait Helpers { /** Decreases metalevel of the type, i.e. transforms: * * c.Expr[T] to T - * * Anything else to Any + * * Nothing to Nothing + * * Anything else to NoType * * @see Metalevels.scala for more information and examples about metalevels */ @@ -86,7 +87,10 @@ trait Helpers { import runDefinitions._ transparentShallowTransform(RepeatedParamClass, tp) { case ExprClassOf(runtimeType) => runtimeType - case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference + // special-casing Nothing here is a useful convention + // that enables no-hassle prototyping with `macro ???` and `macro { ...; ??? }` + case nothing if nothing =:= NothingTpe => NothingTpe + case _ => NoType } } } diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala index d194c095f8..183752d4a2 100644 --- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala +++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala @@ -12,7 +12,8 @@ import scala.reflect.io.{ Directory, File, Path } import java.io.InputStream import java.util.zip.ZipException -import scala.collection.mutable.ListBuffer +import scala.collection.mutable +import mutable.ListBuffer import scala.util.{ Try, Success, Failure } /** Information about a plugin loaded from a jar file. @@ -99,7 +100,7 @@ object Plugin { private def loadDescriptionFromJar(jarp: Path): Try[PluginDescription] = { // XXX Return to this once we have more ARM support def read(is: Option[InputStream]) = is match { - case None => throw new RuntimeException(s"Missing $PluginXML in $jarp") + case None => throw new PluginLoadException(jarp.path, s"Missing $PluginXML in $jarp") case Some(is) => PluginDescription.fromXML(is) } Try(new Jar(jarp.jfile).withEntryStream(PluginXML)(read)) @@ -113,11 +114,14 @@ object Plugin { /** Use a class loader to load the plugin class. */ def load(classname: String, loader: ClassLoader): Try[AnyClass] = { - Try[AnyClass] { - loader loadClass classname - } recoverWith { - case _: Exception => - Failure(new RuntimeException(s"Warning: class not found: ${classname}")) + import scala.util.control.NonFatal + try { + Success[AnyClass](loader loadClass classname) + } catch { + case NonFatal(e) => + Failure(new PluginLoadException(classname, s"Error: unable to load class: $classname")) + case e: NoClassDefFoundError => + Failure(new PluginLoadException(classname, s"Error: class not found: ${e.getMessage} required by $classname")) } } @@ -128,33 +132,54 @@ object Plugin { * A single classloader is created and used to load all of them. */ def loadAllFrom( - jars: List[Path], + paths: List[List[Path]], dirs: List[Path], ignoring: List[String]): List[Try[AnyClass]] = { - // List[(jar, Success(descriptor))] in dir - def scan(d: Directory) = for { - f <- d.files.toList sortBy (_.name) - if Jar isJarOrZip f - pd = loadDescriptionFromJar(f) - if pd.isSuccess - } yield (f, pd) - // (dir, Try(descriptor)) - def explode(d: Directory) = d -> loadDescriptionFromFile(d / PluginXML) - // (j, Try(descriptor)) - def required(j: Path) = j -> loadDescriptionFromJar(j) - - type Paired = Tuple2[Path, Try[PluginDescription]] - val included: List[Paired] = (dirs flatMap (_ ifDirectory scan)).flatten - val exploded: List[Paired] = jars flatMap (_ ifDirectory explode) - val explicit: List[Paired] = jars flatMap (_ ifFile required) - def ignored(p: Paired) = p match { - case (path, Success(pd)) => ignoring contains pd.name - case _ => false + // List[(jar, Try(descriptor))] in dir + def scan(d: Directory) = + d.files.toList sortBy (_.name) filter (Jar isJarOrZip _) map (j => (j, loadDescriptionFromJar(j))) + + type PDResults = List[Try[(PluginDescription, ScalaClassLoader)]] + + // scan plugin dirs for jars containing plugins, ignoring dirs with none and other jars + val fromDirs: PDResults = dirs filter (_.isDirectory) flatMap { d => + scan(d.toDirectory) collect { + case (j, Success(pd)) => Success((pd, loaderFor(Seq(j)))) + } + } + + // scan jar paths for plugins, taking the first plugin you find. + // a path element can be either a plugin.jar or an exploded dir. + def findDescriptor(ps: List[Path]) = { + def loop(qs: List[Path]): Try[PluginDescription] = qs match { + case Nil => Failure(new MissingPluginException(ps)) + case p :: rest => + if (p.isDirectory) loadDescriptionFromFile(p.toDirectory / PluginXML) + else if (p.isFile) loadDescriptionFromJar(p.toFile) + else loop(rest) + } + loop(ps) + } + val fromPaths: PDResults = paths map (p => (p, findDescriptor(p))) map { + case (p, Success(pd)) => Success((pd, loaderFor(p))) + case (_, Failure(e)) => Failure(e) } - val (locs, pds) = ((explicit ::: exploded ::: included) filterNot ignored).unzip - val loader = loaderFor(locs.distinct) - (pds filter (_.isSuccess) map (_.get.classname)).distinct map (Plugin load (_, loader)) + + val seen = mutable.HashSet[String]() + val enabled = (fromPaths ::: fromDirs) map { + case Success((pd, loader)) if seen(pd.classname) => + // a nod to SI-7494, take the plugin classes distinctly + Failure(new PluginLoadException(pd.name, s"Ignoring duplicate plugin ${pd.name} (${pd.classname})")) + case Success((pd, loader)) if ignoring contains pd.name => + Failure(new PluginLoadException(pd.name, s"Disabling plugin ${pd.name}")) + case Success((pd, loader)) => + seen += pd.classname + Plugin.load(pd.classname, loader) + case Failure(e) => + Failure(e) + } + enabled // distinct and not disabled } /** Instantiate a plugin class, given the class and @@ -164,3 +189,11 @@ object Plugin { (clazz getConstructor classOf[Global] newInstance global).asInstanceOf[Plugin] } } + +class PluginLoadException(val path: String, message: String, cause: Exception) extends Exception(message, cause) { + def this(path: String, message: String) = this(path, message, null) +} + +class MissingPluginException(path: String) extends PluginLoadException(path, s"No plugin in path $path") { + def this(paths: List[Path]) = this(paths mkString File.pathSeparator) +} diff --git a/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala b/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala deleted file mode 100644 index c5da24993e..0000000000 --- a/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala +++ /dev/null @@ -1,15 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author Lex Spoon - */ - -package scala.tools.nsc -package plugins - -/** ... - * - * @author Lex Spoon - * @version 1.0, 2007-5-21 - */ -class PluginLoadException(filename: String, cause: Exception) -extends Exception(cause) diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala index 4769705404..12f9aeba27 100644 --- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala +++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala @@ -8,6 +8,7 @@ package scala.tools.nsc package plugins import scala.reflect.io.{ File, Path } +import scala.tools.nsc.util.ClassPath import scala.tools.util.PathResolver.Defaults /** Support for run-time loading of compiler plugins. @@ -16,8 +17,7 @@ import scala.tools.util.PathResolver.Defaults * @version 1.1, 2009/1/2 * Updated 2009/1/2 by Anders Bach Nielsen: Added features to implement SIP 00002 */ -trait Plugins { - self: Global => +trait Plugins { global: Global => /** Load a rough list of the plugins. For speed, it * does not instantiate a compiler run. Therefore it cannot @@ -25,13 +25,20 @@ trait Plugins { * filtered from the final list of plugins. */ protected def loadRoughPluginsList(): List[Plugin] = { - val jars = settings.plugin.value map Path.apply - def injectDefault(s: String) = if (s.isEmpty) Defaults.scalaPluginPath else s - val dirs = (settings.pluginsDir.value split File.pathSeparator).toList map injectDefault map Path.apply - val maybes = Plugin.loadAllFrom(jars, dirs, settings.disable.value) + def asPath(p: String) = ClassPath split p + val paths = settings.plugin.value filter (_ != "") map (s => asPath(s) map Path.apply) + val dirs = { + def injectDefault(s: String) = if (s.isEmpty) Defaults.scalaPluginPath else s + asPath(settings.pluginsDir.value) map injectDefault map Path.apply + } + val maybes = Plugin.loadAllFrom(paths, dirs, settings.disable.value) val (goods, errors) = maybes partition (_.isSuccess) // Explicit parameterization of recover to suppress -Xlint warning about inferred Any - errors foreach (_.recover[Any] { case e: Exception => inform(e.getMessage) }) + errors foreach (_.recover[Any] { + // legacy behavior ignores altogether, so at least warn devs + case e: MissingPluginException => if (global.isDeveloper) warning(e.getMessage) + case e: Exception => inform(e.getMessage) + }) val classes = goods map (_.get) // flatten // Each plugin must only be instantiated once. A common pattern diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 6fe0f34105..6732900ef2 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -714,11 +714,24 @@ abstract class Erasure extends AddInterfaces /** TODO - adapt SymbolPairs so it can be used here. */ private def checkNoDeclaredDoubleDefs(base: Symbol) { val decls = base.info.decls + + // SI-8010 force infos, otherwise makeNotPrivate in ExplicitOuter info transformer can trigger + // a scope rehash while were iterating and we can see the same entry twice! + // Inspection of SymbolPairs (the basis of OverridingPairs), suggests that it is immune + // from this sort of bug as it copies the symbols into a temporary scope *before* any calls to `.info`, + // ie, no variant of it calls `info` or `tpe` in `SymbolPair#exclude`. + // + // Why not just create a temporary scope here? We need to force the name changes in any case before + // we do these checks, so that we're comparing same-named methods based on the expanded names that actually + // end up in the bytecode. + exitingPostErasure(decls.foreach(_.info)) + var e = decls.elems while (e ne null) { if (e.sym.isTerm) { var e1 = decls lookupNextEntry e while (e1 ne null) { + assert(e.sym ne e1.sym, s"Internal error: encountered ${e.sym.debugLocationString} twice during scope traversal. This might be related to SI-8010.") if (sameTypeAfterErasure(e.sym, e1.sym)) doubleDefError(new SymbolPair(base, e.sym, e1.sym)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 2be6d92ed0..53bc9a2772 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -773,7 +773,7 @@ trait Contexts { self: Analyzer => // Implicit collection // - private var implicitsCache: List[List[ImplicitInfo]] = null + private var implicitsCache: List[ImplicitInfo] = null private var implicitsRunId = NoRunId def resetCache() { @@ -832,35 +832,53 @@ trait Contexts { self: Analyzer => * filtered out later by `eligibleInfos` (SI-4270 / 9129cfe9), as they don't type-check. */ def implicitss: List[List[ImplicitInfo]] = { - val imports = this.imports val nextOuter = this.nextOuter - if (implicitsRunId != currentRunId) { - implicitsRunId = currentRunId - implicitsCache = List() - val newImplicits: List[ImplicitInfo] = - if (owner != nextOuter.owner && owner.isClass && !owner.isPackageClass && !inSelfSuperCall) { - if (!owner.isInitialized) return nextOuter.implicitss - // debuglog("collect member implicits " + owner + ", implicit members = " + owner.thisType.implicitMembers)//DEBUG - savingEnclClass(this) { - // !!! In the body of `class C(implicit a: A) { }`, `implicitss` returns `List(List(a), List(a), List(<predef..)))` - // it handled correctly by implicit search, which considers the second `a` to be shadowed, but should be - // remedied nonetheless. - collectImplicits(owner.thisType.implicitMembers, owner.thisType) - } - } else if (scope != nextOuter.scope && !owner.isPackageClass) { - debuglog("collect local implicits " + scope.toList)//DEBUG - collectImplicits(scope, NoPrefix) - } else if (firstImport != nextOuter.firstImport) { - assert(imports.tail.headOption == nextOuter.firstImport, (imports, nextOuter.imports)) - collectImplicitImports(imports.head) - } else if (owner.isPackageClass) { - // the corresponding package object may contain implicit members. - collectImplicits(owner.tpe.implicitMembers, owner.tpe) - } else List() - implicitsCache = if (newImplicits.isEmpty) nextOuter.implicitss - else newImplicits :: nextOuter.implicitss + def withOuter(is: List[ImplicitInfo]): List[List[ImplicitInfo]] = + is match { + case Nil => nextOuter.implicitss + case _ => is :: nextOuter.implicitss + } + + val CycleMarker = NoRunId - 1 + if (implicitsRunId == CycleMarker) { + debuglog(s"cycle while collecting implicits at owner ${owner}, probably due to an implicit without an explicit return type. Continuing with implicits from enclosing contexts.") + withOuter(Nil) + } else if (implicitsRunId != currentRunId) { + implicitsRunId = CycleMarker + implicits(nextOuter) match { + case None => + implicitsRunId = NoRunId + withOuter(Nil) + case Some(is) => + implicitsRunId = currentRunId + implicitsCache = is + withOuter(is) + } } - implicitsCache + else withOuter(implicitsCache) + } + + /** @return None if a cycle is detected, or Some(infos) containing the in-scope implicits at this context */ + private def implicits(nextOuter: Context): Option[List[ImplicitInfo]] = { + val imports = this.imports + if (owner != nextOuter.owner && owner.isClass && !owner.isPackageClass && !inSelfSuperCall) { + if (!owner.isInitialized) None + else savingEnclClass(this) { + // !!! In the body of `class C(implicit a: A) { }`, `implicitss` returns `List(List(a), List(a), List(<predef..)))` + // it handled correctly by implicit search, which considers the second `a` to be shadowed, but should be + // remedied nonetheless. + Some(collectImplicits(owner.thisType.implicitMembers, owner.thisType)) + } + } else if (scope != nextOuter.scope && !owner.isPackageClass) { + debuglog("collect local implicits " + scope.toList)//DEBUG + Some(collectImplicits(scope, NoPrefix)) + } else if (firstImport != nextOuter.firstImport) { + assert(imports.tail.headOption == nextOuter.firstImport, (imports, nextOuter.imports)) + Some(collectImplicitImports(imports.head)) + } else if (owner.isPackageClass) { + // the corresponding package object may contain implicit members. + Some(collectImplicits(owner.tpe.implicitMembers, owner.tpe)) + } else Some(Nil) } // @@ -1108,7 +1126,7 @@ trait Contexts { self: Analyzer => impSym = NoSymbol // Otherwise they are irreconcilably ambiguous else - return ambiguousDefnAndImport(defSym.owner, imp1) + return ambiguousDefnAndImport(defSym.alternatives.head.owner, imp1) } // At this point only one or the other of defSym and impSym might be set. diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala index ba135d7d25..069d6d5fb2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala @@ -391,8 +391,10 @@ trait PatternTypers { else freshUnapplyArgType() ) ) + val unapplyArgTree = Ident(unapplyArg) updateAttachment SubpatternsAttachment(args) + // clearing the type is necessary so that ref will be stabilized; see bug 881 - val fun1 = typedPos(fun.pos)(Apply(Select(fun.clearType(), unapplyMethod), Ident(unapplyArg) :: Nil)) + val fun1 = typedPos(fun.pos)(Apply(Select(fun.clearType(), unapplyMethod), unapplyArgTree :: Nil)) def makeTypedUnApply() = { // the union of the expected type and the inferred type of the argument to unapply diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 38065d5ea8..ec916719dc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1265,22 +1265,22 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans false } - /** If symbol is deprecated, and the point of reference is not enclosed - * in either a deprecated member or a scala bridge method, issue a warning. - */ - private def checkDeprecated(sym: Symbol, pos: Position) { + // Note: if a symbol has both @deprecated and @migration annotations and both + // warnings are enabled, only the first one checked here will be emitted. + // I assume that's a consequence of some code trying to avoid noise by suppressing + // warnings after the first, but I think it'd be better if we didn't have to + // arbitrarily choose one as more important than the other. + private def checkUndesiredProperties(sym: Symbol, pos: Position) { + // If symbol is deprecated, and the point of reference is not enclosed + // in either a deprecated member or a scala bridge method, issue a warning. if (sym.isDeprecated && !currentOwner.ownerChain.exists(x => x.isDeprecated || x.hasBridgeAnnotation)) { unit.deprecationWarning(pos, "%s%s is deprecated%s".format( sym, sym.locationString, sym.deprecationMessage map (": " + _) getOrElse "") ) } - } - - /** Similar to deprecation: check if the symbol is marked with @migration - * indicating it has changed semantics between versions. - */ - private def checkMigration(sym: Symbol, pos: Position) = { - if (sym.hasMigrationAnnotation) { + // Similar to deprecation: check if the symbol is marked with @migration + // indicating it has changed semantics between versions. + if (sym.hasMigrationAnnotation && settings.Xmigration.value != NoScalaVersion) { val changed = try settings.Xmigration.value < ScalaVersion(sym.migrationVersion.get) catch { @@ -1292,9 +1292,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans if (changed) unit.warning(pos, s"${sym.fullLocationString} has changed semantics in version ${sym.migrationVersion.get}:\n${sym.migrationMessage.get}") } - } - - private def checkCompileTimeOnly(sym: Symbol, pos: Position) = { + // See an explanation of compileTimeOnly in its scaladoc at scala.annotation.compileTimeOnly. if (sym.isCompileTimeOnly) { def defaultMsg = sm"""Reference to ${sym.fullLocationString} should not have survived past type checking, @@ -1416,8 +1414,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case TypeRef(pre, sym, args) => tree match { case tt: TypeTree if tt.original == null => // SI-7783 don't warn about inferred types - case _ => - checkDeprecated(sym, tree.pos) + // FIXME: reconcile this check with one in resetAllAttrs + case _ => checkUndesiredProperties(sym, tree.pos) } if(sym.isJavaDefined) sym.typeParams foreach (_.cookJavaRawInfo()) @@ -1449,7 +1447,6 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans private def applyRefchecksToAnnotations(tree: Tree): Unit = { def applyChecks(annots: List[AnnotationInfo]) = { - annots foreach (annot => checkCompileTimeOnly(annot.atp.typeSymbol, annot.pos)) checkAnnotations(annots map (_.atp), tree) transformTrees(annots flatMap (_.args)) } @@ -1541,16 +1538,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans val Select(qual, _) = tree val sym = tree.symbol - /* Note: if a symbol has both @deprecated and @migration annotations and both - * warnings are enabled, only the first one checked here will be emitted. - * I assume that's a consequence of some code trying to avoid noise by suppressing - * warnings after the first, but I think it'd be better if we didn't have to - * arbitrarily choose one as more important than the other. - */ - checkDeprecated(sym, tree.pos) - if(settings.Xmigration.value != NoScalaVersion) - checkMigration(sym, tree.pos) - checkCompileTimeOnly(sym, tree.pos) + checkUndesiredProperties(sym, tree.pos) checkDelayedInitSelect(qual, sym, tree.pos) if (!sym.exists) @@ -1705,7 +1693,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans tree case Ident(name) => - checkCompileTimeOnly(tree.symbol, tree.pos) + checkUndesiredProperties(sym, tree.pos) transformCaseApply(tree, if (name != nme.WILDCARD && name != tpnme.WILDCARD_STAR) { assert(sym != NoSymbol, "transformCaseApply: name = " + name.debugString + " tree = " + tree + " / " + tree.getClass) //debug diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index fb252c3058..5e89440bc0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3746,7 +3746,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val dealiasLocals = new TypeMap { def apply(tp: Type): Type = tp match { case TypeRef(pre, sym, args) => - if (sym.isAliasType && containsLocal(tp)) apply(tp.dealias) + if (sym.isAliasType && containsLocal(tp) && (tp.dealias ne tp)) apply(tp.dealias) else { if (pre.isVolatile) InferTypeWithVolatileTypeSelectionError(tree, pre) @@ -5113,12 +5113,24 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // Warn about likely interpolated strings which are missing their interpolators def warnMissingInterpolator(lit: Literal): Unit = if (!isPastTyper) { + // attempt to avoid warning about trees munged by macros + def isMacroExpansion = { + // context.tree is not the expandee; it is plain new SC(ps).m(args) + //context.tree exists (t => (t.pos includes lit.pos) && hasMacroExpansionAttachment(t)) + // testing pos works and may suffice + //openMacros exists (_.macroApplication.pos includes lit.pos) + // tests whether the lit belongs to the expandee of an open macro + openMacros exists (_.macroApplication.attachments.get[MacroExpansionAttachment] match { + case Some(MacroExpansionAttachment(_, t: Tree)) => t exists (_ == lit) + case _ => false + }) + } // attempt to avoid warning about the special interpolated message string // for implicitNotFound or any standard interpolation (with embedded $$). def isRecognizablyNotForInterpolation = context.enclosingApply.tree match { case Apply(Select(Apply(RefTree(_, nme.StringContext), _), _), _) => true case Apply(Select(New(RefTree(_, tpnme.implicitNotFound)), _), _) => true - case _ => false + case _ => isMacroExpansion } def requiresNoArgs(tp: Type): Boolean = tp match { case PolyType(_, restpe) => requiresNoArgs(restpe) @@ -5149,12 +5161,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } def typedLiteral(tree: Literal) = { - if (settings.lint) - warnMissingInterpolator(tree) + if (settings.lint) warnMissingInterpolator(tree) - tree setType ( - if (tree.value.tag == UnitTag) UnitTpe - else ConstantType(tree.value)) + tree setType (if (tree.value.tag == UnitTag) UnitTpe else ConstantType(tree.value)) } def typedSingletonTypeTree(tree: SingletonTypeTree) = { @@ -5508,7 +5517,23 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) && tree1 != EmptyTree val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty - if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImplRef(ddef, tree1) else AnyTpe + if (isMacroBodyOkay && shouldInheritMacroImplReturnType) { + val commonMessage = "macro defs must have explicitly specified return types" + def reportFailure() = { + ddef.symbol.setFlag(IS_ERROR) + unit.error(ddef.pos, commonMessage) + } + def reportWarning(inferredType: Type) = { + val explanation = s"inference of $inferredType from macro impl's c.Expr[$inferredType] is deprecated and is going to stop working in 2.12" + unit.deprecationWarning(ddef.pos, s"$commonMessage ($explanation)") + } + computeMacroDefTypeFromMacroImplRef(ddef, tree1) match { + case ErrorType => ErrorType + case NothingTpe => NothingTpe + case NoType => reportFailure(); AnyTpe + case tpe => reportWarning(tpe); tpe + } + } else AnyTpe } def transformedOr(tree: Tree, op: => Tree): Tree = transformed remove tree match { diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala index f92c9aa845..f5bcaf68e0 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala @@ -3,6 +3,7 @@ package quasiquotes import scala.collection.{immutable, mutable} import scala.reflect.internal.Flags._ +import scala.reflect.macros.TypecheckException class Cardinality private[Cardinality](val value: Int) extends AnyVal { def pred = { assert(value - 1 >= 0); new Cardinality(value - 1) } @@ -30,158 +31,173 @@ trait Holes { self: Quasiquotes => import definitions._ import universeTypes._ - /** Location characterizes a kind of a non-terminal in Scala syntax where something is going to be spliced. - * A location is typically associated with a type of the things that can be spliced there. - * Associated type might be different from an actual tpe of a splicee due to lifting. - * This is the first pillar of modularity in the quasiquote reifier. - */ - sealed abstract class Location(val tpe: Type) - case object UnknownLocation extends Location(NoType) - case class TreeLocation(override val tpe: Type) extends Location(tpe) - case object NameLocation extends Location(nameType) - case object ModsLocation extends Location(modsType) - case object FlagsLocation extends Location(flagsType) - case object SymbolLocation extends Location(symbolType) - case class IterableLocation(card: Cardinality, sublocation: TreeLocation) extends Location(NoType) { - override val tpe = { - def loop(n: Cardinality, tpe: Type): Type = - if (n == NoDot) tpe - else appliedType(IterableClass.toType, List(loop(n.pred, tpe))) - loop(card, sublocation.tpe) + protected lazy val IterableTParam = IterableClass.typeParams(0).asType.toType + protected def inferParamImplicit(tfun: Type, targ: Type) = c.inferImplicitValue(appliedType(tfun, List(targ)), silent = true) + protected def inferLiftable(tpe: Type): Tree = inferParamImplicit(liftableType, tpe) + protected def inferUnliftable(tpe: Type): Tree = inferParamImplicit(unliftableType, tpe) + protected def isLiftableType(tpe: Type) = inferLiftable(tpe) != EmptyTree + protected def isNativeType(tpe: Type) = + (tpe <:< treeType) || (tpe <:< nameType) || (tpe <:< modsType) || + (tpe <:< flagsType) || (tpe <:< symbolType) + protected def isBottomType(tpe: Type) = + tpe <:< NothingClass.tpe || tpe <:< NullClass.tpe + protected def stripIterable(tpe: Type, limit: Option[Cardinality] = None): (Cardinality, Type) = + if (limit.map { _ == NoDot }.getOrElse { false }) (NoDot, tpe) + else if (tpe != null && !isIterableType(tpe)) (NoDot, tpe) + else if (isBottomType(tpe)) (NoDot, tpe) + else { + val targ = IterableTParam.asSeenFrom(tpe, IterableClass) + val (card, innerTpe) = stripIterable(targ, limit.map { _.pred }) + (card.succ, innerTpe) } + protected def iterableTypeFromCard(n: Cardinality, tpe: Type): Type = { + if (n == NoDot) tpe + else appliedType(IterableClass.toType, List(iterableTypeFromCard(n.pred, tpe))) } - /** Hole type describes location, cardinality and a pre-reification routine associated with a hole. - * An interesting thing about HoleType is that it can be completely inferred from the type of the splicee. - * This is the second pillar of modularity in the quasiquote reifier. + /** Hole encapsulates information about splices in quasiquotes. + * It packs together a cardinality of a splice, pre-reified tree + * representation (possibly preprocessed) and position. */ - case class HoleType(preprocessor: Tree => Tree, location: Location, cardinality: Cardinality) { - def makeHole(tree: Tree) = Hole(preprocessor(tree), location, cardinality) + abstract class Hole { + val tree: Tree + val pos: Position + val cardinality: Cardinality } - object HoleType { - def unapply(tpe: Type): Option[HoleType] = tpe match { - case NativeType(holeTpe) => Some(holeTpe) - case LiftableType(holeTpe) => Some(holeTpe) - case IterableTreeType(holeTpe) => Some(holeTpe) - case IterableLiftableType(holeTpe) => Some(holeTpe) - case _ => None - } - trait HoleTypeExtractor { - def unapply(tpe: Type): Option[HoleType] = { - for { - preprocessor <- this.preprocessor(tpe) - location <- this.location(tpe) - cardinality <- Some(this.cardinality(tpe)) - } yield HoleType(preprocessor, location, cardinality) - } - def preprocessor(tpe: Type): Option[Tree => Tree] - def location(tpe: Type): Option[Location] - def cardinality(tpe: Type): Cardinality = parseCardinality(tpe)._1 - - def lifter(tpe: Type): Option[Tree => Tree] = { - val lifterTpe = appliedType(LiftableClass.toType, List(tpe)) - val lifter = c.inferImplicitValue(lifterTpe, silent = true) - if (lifter != EmptyTree) Some(tree => { - val lifted = Apply(lifter, List(u, tree)) - val targetType = Select(u, tpnme.Tree) - atPos(tree.pos)(TypeApply(Select(lifted, nme.asInstanceOf_), List(targetType))) - }) else None - } + object Hole { + def apply(card: Cardinality, tree: Tree): Hole = + if (method != nme.unapply) new ApplyHole(card, tree) + else new UnapplyHole(card, tree) + def unapply(hole: Hole): Some[(Tree, Cardinality)] = Some((hole.tree, hole.cardinality)) + } - def iterator(tpe: Type)(elementTransform: Tree => Tree): Option[Tree => Tree] = { - def reifyIterable(tree: Tree, n: Cardinality): Tree = { - def loop(tree: Tree, n: Cardinality) = - if (n == NoDot) elementTransform(tree) - else { - val x: TermName = c.freshName() - val wrapped = reifyIterable(Ident(x), n.pred) - val xToWrapped = Function(List(ValDef(Modifiers(PARAM), x, TypeTree(), EmptyTree)), wrapped) - Select(Apply(Select(tree, nme.map), List(xToWrapped)), nme.toList) - } - if (tree.tpe != null && (tree.tpe <:< listTreeType || tree.tpe <:< listListTreeType)) tree - else atPos(tree.pos)(loop(tree, n)) - } - val card = parseCardinality(tpe)._1 - if (card != NoDot) Some(reifyIterable(_, card)) else None - } + class ApplyHole(card: Cardinality, splicee: Tree) extends Hole { + val (strippedTpe, tpe): (Type, Type) = { + if (stripIterable(splicee.tpe)._1.value < card.value) cantSplice() + val (_, strippedTpe) = stripIterable(splicee.tpe, limit = Some(card)) + if (isBottomType(strippedTpe)) cantSplice() + else if (isNativeType(strippedTpe)) (strippedTpe, iterableTypeFromCard(card, strippedTpe)) + else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromCard(card, treeType)) + else cantSplice() } - object NativeType extends HoleTypeExtractor { - def preprocessor(tpe: Type) = Some(identity) - def location(tpe: Type) = { - if (tpe <:< treeType) Some(TreeLocation(tpe)) - else if (tpe <:< nameType) Some(NameLocation) - else if (tpe <:< modsType) Some(ModsLocation) - else if (tpe <:< flagsType) Some(FlagsLocation) - else if (tpe <:< symbolType) Some(SymbolLocation) - else None - } + val tree = { + def inner(itpe: Type)(tree: Tree) = + if (isNativeType(itpe)) tree + else if (isLiftableType(itpe)) lifted(itpe)(tree) + else global.abort("unreachable") + if (card == NoDot) inner(strippedTpe)(splicee) + else iterated(card, strippedTpe, inner(strippedTpe))(splicee) } - object LiftableType extends HoleTypeExtractor { - def preprocessor(tpe: Type) = lifter(tpe) - def location(tpe: Type) = Some(TreeLocation(treeType)) + val pos = splicee.pos + + val cardinality = stripIterable(tpe)._1 + + protected def cantSplice(): Nothing = { + val (iterableCard, iterableType) = stripIterable(splicee.tpe) + val holeCardMsg = if (card != NoDot) s" with $card" else "" + val action = "splice " + splicee.tpe + holeCardMsg + val suggestCard = card != iterableCard || card != NoDot + val spliceeCardMsg = if (card != iterableCard && iterableCard != NoDot) s"using $iterableCard" else "omitting the dots" + val cardSuggestion = if (suggestCard) spliceeCardMsg else "" + val suggestLifting = (card == NoDot || iterableCard != NoDot) && !(iterableType <:< treeType) && !isLiftableType(iterableType) + val liftedTpe = if (card != NoDot) iterableType else splicee.tpe + val liftSuggestion = if (suggestLifting) s"providing an implicit instance of Liftable[$liftedTpe]" else "" + val advice = + if (isBottomType(iterableType)) "bottom type values often indicate programmer mistake" + else "consider " + List(cardSuggestion, liftSuggestion).filter(_ != "").mkString(" or ") + c.abort(splicee.pos, s"Can't $action, $advice") } - object IterableTreeType extends HoleTypeExtractor { - def preprocessor(tpe: Type) = iterator(tpe)(identity) - def location(tpe: Type) = { - val (card, elementTpe) = parseCardinality(tpe) - if (card != NoDot && elementTpe <:< treeType) Some(IterableLocation(card, TreeLocation(elementTpe))) - else None - } + protected def lifted(tpe: Type)(tree: Tree): Tree = { + val lifter = inferLiftable(tpe) + assert(lifter != EmptyTree, s"couldnt find a liftable for $tpe") + val lifted = Apply(lifter, List(tree)) + val targetType = Select(u, tpnme.Tree) + atPos(tree.pos)(TypeApply(Select(lifted, nme.asInstanceOf_), List(targetType))) } - object IterableLiftableType extends HoleTypeExtractor { - def preprocessor(tpe: Type) = { - val (_, elementTpe) = parseCardinality(tpe) - for { - lifter <- this.lifter(elementTpe) - iterator <- this.iterator(tpe)(lifter) - } yield iterator + protected def iterated(card: Cardinality, tpe: Type, elementTransform: Tree => Tree = identity)(tree: Tree): Tree = { + assert(card != NoDot) + def reifyIterable(tree: Tree, n: Cardinality): Tree = { + def loop(tree: Tree, n: Cardinality): Tree = + if (n == NoDot) elementTransform(tree) + else { + val x: TermName = c.freshName() + val wrapped = reifyIterable(Ident(x), n.pred) + val xToWrapped = Function(List(ValDef(Modifiers(PARAM), x, TypeTree(), EmptyTree)), wrapped) + Select(Apply(Select(tree, nme.map), List(xToWrapped)), nme.toList) + } + if (tree.tpe != null && (tree.tpe <:< listTreeType || tree.tpe <:< listListTreeType)) tree + else atPos(tree.pos)(loop(tree, n)) } - def location(tpe: Type) = Some(IterableLocation(cardinality(tpe), TreeLocation(treeType))) + reifyIterable(tree, card) } } - /** Hole encapsulates information about splices in quasiquotes. - * It packs together a cardinality of a splice, a splicee (possibly preprocessed) - * and the description of the location in Scala syntax where the splicee can be spliced. - * This is the third pillar of modularity in the quasiquote reifier. - */ - case class Hole(tree: Tree, location: Location, cardinality: Cardinality) - - object Hole { - def apply(splicee: Tree, holeCard: Cardinality): Hole = { - if (method == nme.unapply) return new Hole(splicee, UnknownLocation, holeCard) - val (spliceeCard, elementTpe) = parseCardinality(splicee.tpe) - def cantSplice() = { - val holeCardMsg = if (holeCard != NoDot) s" with $holeCard" else "" - val action = "splice " + splicee.tpe + holeCardMsg - val suggestCard = holeCard != spliceeCard || holeCard != NoDot - val spliceeCardMsg = if (holeCard != spliceeCard && spliceeCard != NoDot) s"using $spliceeCard" else "omitting the dots" - val cardSuggestion = if (suggestCard) spliceeCardMsg else "" - def canBeLifted(tpe: Type) = HoleType.LiftableType.unapply(tpe).nonEmpty - val suggestLifting = (holeCard == NoDot || spliceeCard != NoDot) && !(elementTpe <:< treeType) && !canBeLifted(elementTpe) - val liftedTpe = if (holeCard != NoDot) elementTpe else splicee.tpe - val liftSuggestion = if (suggestLifting) s"providing an implicit instance of Liftable[$liftedTpe]" else "" - val advice = List(cardSuggestion, liftSuggestion).filter(_ != "").mkString(" or ") - c.abort(splicee.pos, s"Can't $action, consider $advice") - } - val holeTpe = splicee.tpe match { - case _ if holeCard != spliceeCard => cantSplice() - case HoleType(holeTpe) => holeTpe - case _ => cantSplice() - } - holeTpe.makeHole(splicee) + class UnapplyHole(val cardinality: Cardinality, pat: Tree) extends Hole { + val (placeholderName, pos, tptopt) = pat match { + case Bind(pname, inner @ Bind(_, Typed(Ident(nme.WILDCARD), tpt))) => (pname, inner.pos, Some(tpt)) + case Bind(pname, inner @ Typed(Ident(nme.WILDCARD), tpt)) => (pname, inner.pos, Some(tpt)) + case Bind(pname, inner) => (pname, inner.pos, None) } + val treeNoUnlift = Bind(placeholderName, Ident(nme.WILDCARD)) + lazy val tree = + tptopt.map { tpt => + val TypeDef(_, _, _, typedTpt) = + try c.typeCheck(TypeDef(NoMods, TypeName("T"), Nil, tpt)) + catch { case TypecheckException(pos, msg) => c.abort(pos.asInstanceOf[c.Position], msg) } + val tpe = typedTpt.tpe + val (iterableCard, _) = stripIterable(tpe) + if (iterableCard.value < cardinality.value) + c.abort(pat.pos, s"Can't extract $tpe with $cardinality, consider using $iterableCard") + val (_, strippedTpe) = stripIterable(tpe, limit = Some(cardinality)) + if (strippedTpe <:< treeType) treeNoUnlift + else + unlifters.spawn(strippedTpe, cardinality).map { + Apply(_, treeNoUnlift :: Nil) + }.getOrElse { + c.abort(pat.pos, s"Can't find $unliftableType[$strippedTpe], consider providing it") + } + }.getOrElse { treeNoUnlift } } - def parseCardinality(tpe: Type): (Cardinality, Type) = { - if (tpe != null && isIterableType(tpe)) { - val (card, innerTpe) = parseCardinality(tpe.typeArguments.head) - (card.succ, innerTpe) - } else (NoDot, tpe) + /** Full support for unliftable implies that it's possible to interleave + * deconstruction with higher cardinality and unlifting of the values. + * In particular extraction of List[Tree] as List[T: Unliftable] requires + * helper extractors that would do the job: UnliftHelper1[T]. Similarly + * List[List[Tree]] needs UnliftHelper2[T]. + * + * See also "unlift list" tests in UnapplyProps.scala + */ + object unlifters { + private var records = List.empty[(Type, Cardinality)] + // Request an UnliftHelperN[T] where n == card and T == tpe. + // If card == 0 then helper is not needed and plain instance + // of unliftable is returned. + def spawn(tpe: Type, card: Cardinality): Option[Tree] = { + val unlifter = inferUnliftable(tpe) + if (unlifter == EmptyTree) None + else if (card == NoDot) Some(unlifter) + else { + val idx = records.indexWhere { p => p._1 =:= tpe && p._2 == card } + val resIdx = if (idx != -1) idx else { records +:= (tpe, card); records.length - 1} + Some(Ident(TermName(nme.QUASIQUOTE_UNLIFT_HELPER + resIdx))) + } + } + // Returns a list of vals that will defined required unlifters + def preamble(): List[Tree] = + records.zipWithIndex.map { case ((tpe, card), idx) => + val name = TermName(nme.QUASIQUOTE_UNLIFT_HELPER + idx) + val helperName = card match { case DotDot => nme.UnliftHelper1 case DotDotDot => nme.UnliftHelper2 } + val lifter = inferUnliftable(tpe) + assert(helperName.isTermName) + // q"val $name: $u.build.${helperName.toTypeName} = $u.build.$helperName($lifter)" + ValDef(NoMods, name, + AppliedTypeTree(Select(Select(u, nme.build), helperName.toTypeName), List(TypeTree(tpe))), + Apply(Select(Select(u, nme.build), helperName), lifter :: Nil)) + } } -}
\ No newline at end of file +} diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala index 126c14ac81..6e6b617e5c 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala @@ -161,7 +161,12 @@ trait Parsers { self: Quasiquotes => } object TermParser extends Parser { - def entryPoint = { parser => gen.mkTreeOrBlock(parser.templateOrTopStatSeq()) } + def entryPoint = { parser => + parser.templateOrTopStatSeq() match { + case head :: Nil => Block(Nil, head) + case lst => gen.mkTreeOrBlock(lst) + } + } } object TypeParser extends Parser { diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala index 54be9123c7..bdb44ad9a2 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala @@ -13,6 +13,7 @@ import scala.collection.{immutable, mutable} trait Placeholders { self: Quasiquotes => import global._ import Cardinality._ + import universeTypes._ // Step 1: Transform Scala source with holes into vanilla Scala source @@ -32,13 +33,17 @@ trait Placeholders { self: Quasiquotes => def appendHole(tree: Tree, cardinality: Cardinality) = { val placeholderName = c.freshName(TermName(nme.QUASIQUOTE_PREFIX + sessionSuffix)) sb.append(placeholderName) - val holeTree = if (method == nme.unapply) Bind(placeholderName, Ident(nme.WILDCARD)) else tree - holeMap(placeholderName) = Hole(holeTree, cardinality) + val holeTree = + if (method != nme.unapply) tree + else Bind(placeholderName, tree) + holeMap(placeholderName) = Hole(cardinality, holeTree) } val iargs = method match { case nme.apply => args - case nme.unapply => List.fill(parts.length - 1)(EmptyTree) + case nme.unapply => + val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args + dummy.attachments.get[SubpatternsAttachment].get.patterns case _ => global.abort("unreachable") } @@ -78,9 +83,9 @@ trait Placeholders { self: Quasiquotes => trait HolePlaceholder { def matching: PartialFunction[Any, Name] - def unapply(scrutinee: Any): Option[(Tree, Location, Cardinality)] = { + def unapply(scrutinee: Any): Option[Hole] = { val name = matching.lift(scrutinee) - name.flatMap { holeMap.get(_).map { case Hole(repr, loc, card) => (repr, loc, card) } } + name.flatMap { holeMap.get(_) } } } @@ -128,44 +133,44 @@ trait Placeholders { self: Quasiquotes => } object SymbolPlaceholder { - def unapply(scrutinee: Any): Option[Tree] = scrutinee match { - case Placeholder(tree, SymbolLocation, _) => Some(tree) + def unapply(scrutinee: Any): Option[Hole] = scrutinee match { + case Placeholder(hole: ApplyHole) if hole.tpe <:< symbolType => Some(hole) case _ => None } } object CasePlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(tree, location, card))), EmptyTree, EmptyTree) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(hole))), EmptyTree, EmptyTree) => Some(hole) case _ => None } } object RefineStatPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some(hole) case _ => None } } object EarlyDefPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some(hole) case _ => None } } object PackageStatPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case ValDef(NoMods, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case ValDef(NoMods, Placeholder(hole), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some(hole) case _ => None } } object ForEnumPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case build.SyntacticValFrom(Bind(Placeholder(tree, location, card), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) => - Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case build.SyntacticValFrom(Bind(Placeholder(hole), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) => + Some(hole) case _ => None } } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index b28c85cfc2..6d7aafe266 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -13,7 +13,7 @@ trait Reifiers { self: Quasiquotes => import Cardinality._ import universeTypes._ - abstract class Reifier extends { + abstract class Reifier(val isReifyingExpressions: Boolean) extends { val global: self.global.type = self.global val universe = self.universe val reifee = EmptyTree @@ -22,7 +22,6 @@ trait Reifiers { self: Quasiquotes => } with ReflectReifier { lazy val typer = throw new UnsupportedOperationException - def isReifyingExpressions: Boolean def isReifyingPatterns: Boolean = !isReifyingExpressions def action = if (isReifyingExpressions) "splice" else "extract" def holesHaveTypes = isReifyingExpressions @@ -94,12 +93,12 @@ trait Reifiers { self: Quasiquotes => // cq"$tree if $guard => $succ" :: cq"_ => $fail" :: Nil CaseDef(tree, guard, succ) :: CaseDef(Ident(nme.WILDCARD), EmptyTree, fail) :: Nil } - // q"new { def unapply(tree: $AnyClass) = tree match { case ..$cases } }.unapply(..$args)" + // q"new { def unapply(tree: $AnyClass) = { ..${unlifters.preamble()}; tree match { case ..$cases } } }.unapply(..$args)" Apply( Select( SyntacticNew(Nil, Nil, noSelfType, List( DefDef(NoMods, nme.unapply, Nil, List(List(ValDef(NoMods, nme.tree, TypeTree(AnyClass.toType), EmptyTree))), TypeTree(), - Match(Ident(nme.tree), cases)))), + SyntacticBlock(unlifters.preamble() :+ Match(Ident(nme.tree), cases))))), nme.unapply), args) } @@ -107,7 +106,7 @@ trait Reifiers { self: Quasiquotes => def reifyFillingHoles(tree: Tree): Tree = { val reified = reifyTree(tree) holeMap.unused.foreach { hole => - c.abort(holeMap(hole).tree.pos, s"Don't know how to $action here") + c.abort(holeMap(hole).pos, s"Don't know how to $action here") } wrap(reified) } @@ -117,21 +116,27 @@ trait Reifiers { self: Quasiquotes => reifyTreeSyntactically(tree) def reifyTreePlaceholder(tree: Tree): Tree = tree match { - case Placeholder(tree, TreeLocation(_), _) if isReifyingExpressions => tree - case Placeholder(tree, _, NoDot) if isReifyingPatterns => tree - case Placeholder(tree, _, card @ Dot()) => c.abort(tree.pos, s"Can't $action with $card here") + case Placeholder(hole: ApplyHole) if hole.tpe <:< treeType => hole.tree + case Placeholder(Hole(tree, NoDot)) if isReifyingPatterns => tree + case Placeholder(hole @ Hole(_, card @ Dot())) => c.abort(hole.pos, s"Can't $action with $card here") case TuplePlaceholder(args) => reifyTuple(args) case TupleTypePlaceholder(args) => reifyTupleType(args) case FunctionTypePlaceholder(argtpes, restpe) => reifyFunctionType(argtpes, restpe) - case CasePlaceholder(tree, location, _) => reifyCase(tree, location) - case RefineStatPlaceholder(tree, _, _) => reifyRefineStat(tree) - case EarlyDefPlaceholder(tree, _, _) => reifyEarlyDef(tree) - case PackageStatPlaceholder(tree, _, _) => reifyPackageStat(tree) - case ForEnumPlaceholder(tree, _, _) => tree + case CasePlaceholder(hole) => hole.tree + case RefineStatPlaceholder(hole) => reifyRefineStat(hole) + case EarlyDefPlaceholder(hole) => reifyEarlyDef(hole) + case PackageStatPlaceholder(hole) => reifyPackageStat(hole) + // for enumerators are checked not during splicing but during + // desugaring of the for loop in SyntacticFor & SyntacticForYield + case ForEnumPlaceholder(hole) => hole.tree case _ => EmptyTree } override def reifyTreeSyntactically(tree: Tree) = tree match { + case RefTree(qual, SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions => + mirrorBuildCall(nme.RefTree, reify(qual), tree) + case This(SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions => + mirrorCall(nme.This, tree) case SyntacticTraitDef(mods, name, tparams, earlyDefs, parents, selfdef, body) => reifyBuildCall(nme.SyntacticTraitDef, mods, name, tparams, earlyDefs, parents, selfdef, body) case SyntacticClassDef(mods, name, tparams, constrmods, vparamss, earlyDefs, parents, selfdef, body) => @@ -161,17 +166,24 @@ trait Reifiers { self: Quasiquotes => reifyBuildCall(nme.SyntacticForYield, enums, body) case SyntacticAssign(lhs, rhs) => reifyBuildCall(nme.SyntacticAssign, lhs, rhs) - case SyntacticApplied(fun, List(args)) - if args.forall { case Placeholder(_, _, DotDotDot) => false case _ => true } => - reifyBuildCall(nme.SyntacticApply, fun, args) case SyntacticApplied(fun, argss) if argss.nonEmpty => reifyBuildCall(nme.SyntacticApplied, fun, argss) case SyntacticTypeApplied(fun, targs) if targs.nonEmpty => reifyBuildCall(nme.SyntacticTypeApplied, fun, targs) case SyntacticFunction(args, body) => reifyBuildCall(nme.SyntacticFunction, args, body) + case SyntacticIdent(name, isBackquoted) => + reifyBuildCall(nme.SyntacticIdent, name, isBackquoted) + case Block(Nil, Placeholder(Hole(tree, DotDot))) => + mirrorBuildCall(nme.SyntacticBlock, tree) + case Block(Nil, other) => + reifyTree(other) case Block(stats, last) => reifyBuildCall(nme.SyntacticBlock, stats :+ last) + case Try(block, catches, finalizer) => + reifyBuildCall(nme.SyntacticTry, block, catches, finalizer) + case Match(selector, cases) => + reifyBuildCall(nme.SyntacticMatch, selector, cases) // parser emits trees with scala package symbol to ensure // that some names hygienically point to various scala package // members; we need to preserve this symbol to preserve @@ -183,9 +195,10 @@ trait Reifiers { self: Quasiquotes => } override def reifyName(name: Name): Tree = name match { - case Placeholder(tree, location, _) => - if (holesHaveTypes && !(location.tpe <:< nameType)) c.abort(tree.pos, s"$nameType expected but ${location.tpe} found") - tree + case Placeholder(hole: ApplyHole) => + if (!(hole.tpe <:< nameType)) c.abort(hole.pos, s"$nameType expected but ${hole.tpe} found") + hole.tree + case Placeholder(hole: UnapplyHole) => hole.treeNoUnlift case FreshName(prefix) if prefix != nme.QUASIQUOTE_NAME_PREFIX => def fresh() = c.freshName[TermName](nme.QUASIQUOTE_NAME_PREFIX) def introduceName() = { val n = fresh(); nameMap(name) += n; n} @@ -196,15 +209,10 @@ trait Reifiers { self: Quasiquotes => super.reifyName(name) } - def reifyCase(tree: Tree, location: Location) = { - if (holesHaveTypes && !(location.tpe <:< caseDefType)) c.abort(tree.pos, s"$caseDefType expected but ${location.tpe} found") - tree - } - def reifyTuple(args: List[Tree]) = args match { case Nil => reify(Literal(Constant(()))) - case List(hole @ Placeholder(_, _, NoDot)) => reify(hole) - case List(Placeholder(_, _, _)) => reifyBuildCall(nme.SyntacticTuple, args) + case List(hole @ Placeholder(Hole(_, NoDot))) => reify(hole) + case List(Placeholder(_)) => reifyBuildCall(nme.SyntacticTuple, args) // in a case we only have one element tuple without // any cardinality annotations this means that this is // just an expression wrapped in parentheses @@ -214,8 +222,8 @@ trait Reifiers { self: Quasiquotes => def reifyTupleType(args: List[Tree]) = args match { case Nil => reify(Select(Ident(nme.scala_), tpnme.Unit)) - case List(hole @ Placeholder(_, _, NoDot)) => reify(hole) - case List(Placeholder(_, _, _)) => reifyBuildCall(nme.SyntacticTupleType, args) + case List(hole @ Placeholder(Hole(_, NoDot))) => reify(hole) + case List(Placeholder(_)) => reifyBuildCall(nme.SyntacticTupleType, args) case List(other) => reify(other) case _ => reifyBuildCall(nme.SyntacticTupleType, args) } @@ -223,13 +231,18 @@ trait Reifiers { self: Quasiquotes => def reifyFunctionType(argtpes: List[Tree], restpe: Tree) = reifyBuildCall(nme.SyntacticFunctionType, argtpes, restpe) - def reifyRefineStat(tree: Tree) = tree + def reifyConstructionCheck(name: TermName, hole: Hole) = hole match { + case _: UnapplyHole => hole.tree + case _: ApplyHole => mirrorBuildCall(name, hole.tree) + } + + def reifyRefineStat(hole: Hole) = reifyConstructionCheck(nme.mkRefineStat, hole) - def reifyEarlyDef(tree: Tree) = tree + def reifyEarlyDef(hole: Hole) = reifyConstructionCheck(nme.mkEarlyDef, hole) - def reifyAnnotation(tree: Tree) = tree + def reifyAnnotation(hole: Hole) = reifyConstructionCheck(nme.mkAnnotation, hole) - def reifyPackageStat(tree: Tree) = tree + def reifyPackageStat(hole: Hole) = reifyConstructionCheck(nme.mkPackageStat, hole) /** Splits list into a list of groups where subsequent elements are considered * similar by the corresponding function. @@ -262,7 +275,7 @@ trait Reifiers { self: Quasiquotes => * * reifyMultiCardinalityList(lst) { * // first we define patterns that extract high-cardinality holeMap (currently ..) - * case Placeholder(CorrespondsTo(tree, tpe)) if tpe <:< iterableTreeType => tree + * case Placeholder(IterableType(_, _)) => tree * } { * // in the end we define how single elements are reified, typically with default reify call * reify(_) @@ -281,21 +294,22 @@ trait Reifiers { self: Quasiquotes => * elements. */ override def reifyList(xs: List[Any]): Tree = reifyMultiCardinalityList(xs) { - case Placeholder(tree, _, DotDot) => tree - case CasePlaceholder(tree, _, DotDot) => tree - case RefineStatPlaceholder(tree, _, DotDot) => reifyRefineStat(tree) - case EarlyDefPlaceholder(tree, _, DotDot) => reifyEarlyDef(tree) - case PackageStatPlaceholder(tree, _, DotDot) => reifyPackageStat(tree) - case ForEnumPlaceholder(tree, _, DotDot) => tree - case List(Placeholder(tree, _, DotDotDot)) => tree + case Placeholder(Hole(tree, DotDot)) => tree + case CasePlaceholder(Hole(tree, DotDot)) => tree + case RefineStatPlaceholder(h @ Hole(_, DotDot)) => reifyRefineStat(h) + case EarlyDefPlaceholder(h @ Hole(_, DotDot)) => reifyEarlyDef(h) + case PackageStatPlaceholder(h @ Hole(_, DotDot)) => reifyPackageStat(h) + case ForEnumPlaceholder(Hole(tree, DotDot)) => tree + case List(Placeholder(Hole(tree, DotDotDot))) => tree } { reify(_) } def reifyAnnotList(annots: List[Tree]): Tree = reifyMultiCardinalityList(annots) { - case AnnotPlaceholder(tree, _, DotDot) => reifyAnnotation(tree) + case AnnotPlaceholder(h @ Hole(_, DotDot)) => reifyAnnotation(h) } { - case AnnotPlaceholder(tree, UnknownLocation | TreeLocation(_), NoDot) => reifyAnnotation(tree) + case AnnotPlaceholder(h: ApplyHole) if h.tpe <:< treeType => reifyAnnotation(h) + case AnnotPlaceholder(h: UnapplyHole) if h.cardinality == NoDot => reifyAnnotation(h) case other => reify(other) } @@ -321,78 +335,55 @@ trait Reifiers { self: Quasiquotes => override def mirrorBuildCall(name: TermName, args: Tree*): Tree = Apply(Select(Select(universe, nme.build), name), args.toList) - } - - class ApplyReifier extends Reifier { - def isReifyingExpressions = true - override def reifyTreeSyntactically(tree: Tree): Tree = tree match { - case RefTree(qual, SymbolPlaceholder(tree)) => - mirrorBuildCall(nme.RefTree, reify(qual), tree) - case This(SymbolPlaceholder(tree)) => - mirrorCall(nme.This, tree) - case _ => - super.reifyTreeSyntactically(tree) - } + override def scalaFactoryCall(name: String, args: Tree*): Tree = + call("scala." + name, args: _*) + } - override def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree = xs match { - case Nil => mkList(Nil) - case _ => + class ApplyReifier extends Reifier(isReifyingExpressions = true) { + def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree = + if (xs.isEmpty) mkList(Nil) + else { def reifyGroup(group: List[T]): Tree = group match { case List(elem) if fill.isDefinedAt(elem) => fill(elem) case elems => mkList(elems.map(fallback)) } val head :: tail = group(xs) { (a, b) => !fill.isDefinedAt(a) && !fill.isDefinedAt(b) } tail.foldLeft[Tree](reifyGroup(head)) { (tree, lst) => Apply(Select(tree, nme.PLUSPLUS), List(reifyGroup(lst))) } - } + } override def reifyModifiers(m: Modifiers) = if (m == NoMods) super.reifyModifiers(m) else { val (modsPlaceholders, annots) = m.annotations.partition { - case ModsPlaceholder(_, _, _) => true + case ModsPlaceholder(_) => true case _ => false } val (mods, flags) = modsPlaceholders.map { - case ModsPlaceholder(tree, location, card) => (tree, location) - }.partition { case (tree, location) => - location match { - case ModsLocation => true - case FlagsLocation => false - case _ => c.abort(tree.pos, s"$flagsType or $modsType expected but ${tree.tpe} found") - } + case ModsPlaceholder(hole: ApplyHole) => hole + }.partition { hole => + if (hole.tpe <:< modsType) true + else if (hole.tpe <:< flagsType) false + else c.abort(hole.pos, s"$flagsType or $modsType expected but ${hole.tpe} found") } mods match { - case (tree, _) :: Nil => - if (flags.nonEmpty) c.abort(flags(0)._1.pos, "Can't splice flags together with modifiers, consider merging flags into modifiers") - if (annots.nonEmpty) c.abort(tree.pos, "Can't splice modifiers together with annotations, consider merging annotations into modifiers") - ensureNoExplicitFlags(m, tree.pos) - tree - case _ :: (second, _) :: Nil => - c.abort(second.pos, "Can't splice multiple modifiers, consider merging them into a single modifiers instance") + case hole :: Nil => + if (flags.nonEmpty) c.abort(flags(0).pos, "Can't splice flags together with modifiers, consider merging flags into modifiers") + if (annots.nonEmpty) c.abort(hole.pos, "Can't splice modifiers together with annotations, consider merging annotations into modifiers") + ensureNoExplicitFlags(m, hole.pos) + hole.tree + case _ :: hole :: Nil => + c.abort(hole.pos, "Can't splice multiple modifiers, consider merging them into a single modifiers instance") case _ => val baseFlags = reifyFlags(m.flags) - val reifiedFlags = flags.foldLeft[Tree](baseFlags) { case (flag, (tree, _)) => Apply(Select(flag, nme.OR), List(tree)) } + val reifiedFlags = flags.foldLeft[Tree](baseFlags) { case (flag, hole) => Apply(Select(flag, nme.OR), List(hole.tree)) } mirrorFactoryCall(nme.Modifiers, reifiedFlags, reify(m.privateWithin), reifyAnnotList(annots)) } } - override def reifyRefineStat(tree: Tree) = mirrorBuildCall(nme.mkRefineStat, tree) - - override def reifyEarlyDef(tree: Tree) = mirrorBuildCall(nme.mkEarlyDef, tree) - - override def reifyAnnotation(tree: Tree) = mirrorBuildCall(nme.mkAnnotation, tree) - - override def reifyPackageStat(tree: Tree) = mirrorBuildCall(nme.mkPackageStat, tree) } - - class UnapplyReifier extends Reifier { - def isReifyingExpressions = false - - override def scalaFactoryCall(name: String, args: Tree*): Tree = - call("scala." + name, args: _*) - - override def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree) = xs match { + class UnapplyReifier extends Reifier(isReifyingExpressions = false) { + def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree = xs match { case init :+ last if fill.isDefinedAt(last) => init.foldRight[Tree](fill(last)) { (el, rest) => val cons = Select(Select(Select(Ident(nme.scala_), nme.collection), nme.immutable), nme.CONS) @@ -405,14 +396,14 @@ trait Reifiers { self: Quasiquotes => override def reifyModifiers(m: Modifiers) = if (m == NoMods) super.reifyModifiers(m) else { - val mods = m.annotations.collect { case ModsPlaceholder(tree, _, _) => tree } + val mods = m.annotations.collect { case ModsPlaceholder(hole: UnapplyHole) => hole } mods match { - case tree :: Nil => - if (m.annotations.length != 1) c.abort(tree.pos, "Can't extract modifiers together with annotations, consider extracting just modifiers") - ensureNoExplicitFlags(m, tree.pos) - tree - case _ :: second :: rest => - c.abort(second.pos, "Can't extract multiple modifiers together, consider extracting a single modifiers instance") + case hole :: Nil => + if (m.annotations.length != 1) c.abort(hole.pos, "Can't extract modifiers together with annotations, consider extracting just modifiers") + ensureNoExplicitFlags(m, hole.pos) + hole.treeNoUnlift + case _ :: hole :: _ => + c.abort(hole.pos, "Can't extract multiple modifiers together, consider extracting a single modifiers instance") case Nil => mirrorFactoryCall(nme.Modifiers, reifyFlags(m.flags), reify(m.privateWithin), reifyAnnotList(m.annotations)) } diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 467a210cab..27f10ff00a 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -1018,7 +1018,11 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") val enclosing = new Members[ScopeMember] def addScopeMember(sym: Symbol, pre: Type, viaImport: Tree) = locals.add(sym, pre, implicitlyAdded = false) { (s, st) => - new ScopeMember(s, st, context.isAccessible(s, pre, superAccess = false), viaImport) + // imported val and var are always marked as inaccessible, but they could be accessed through their getters. SI-7995 + if (s.hasGetter) + new ScopeMember(s, st, context.isAccessible(s.getter, pre, superAccess = false), viaImport) + else + new ScopeMember(s, st, context.isAccessible(s, pre, superAccess = false), viaImport) } def localsToEnclosing() = { enclosing.addNonShadowed(locals) @@ -1234,6 +1238,18 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") } } + // We need to force a number of symbols that might be touched by a parser. + // Otherwise thread safety property of parseTree method would be violated. + protected def forceSymbolsUsedByParser(): Unit = { + val symbols = + Set(UnitClass, BooleanClass, ByteClass, + ShortClass, IntClass, LongClass, FloatClass, + DoubleClass, NilModule, ListClass) ++ TupleClass.seq + symbols.foreach(_.initialize) + } + + forceSymbolsUsedByParser() + /** The compiler has been initialized. Constructors are evaluated in textual order, * so this is set to true only after all super constructors and the primary constructor * have been executed. diff --git a/src/library/scala/MatchError.scala b/src/library/scala/MatchError.scala index 6ba7e833d3..9965bb19b5 100644 --- a/src/library/scala/MatchError.scala +++ b/src/library/scala/MatchError.scala @@ -23,9 +23,15 @@ final class MatchError(obj: Any) extends RuntimeException { /** There's no reason we need to call toString eagerly, * so defer it until getMessage is called. */ - private lazy val objString = + private lazy val objString = { + def ofClass = "of class " + obj.getClass.getName if (obj == null) "null" - else obj.toString() + " (of class " + obj.getClass.getName + ")" + else try { + obj.toString() + " (" + ofClass + ")" + } catch { + case _: Throwable => "an instance " + ofClass + } + } override def getMessage() = objString } diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala index 05c5dd799d..264304db68 100644 --- a/src/library/scala/collection/immutable/Queue.scala +++ b/src/library/scala/collection/immutable/Queue.scala @@ -89,6 +89,16 @@ class Queue[+A] protected(protected val in: List[A], protected val out: List[A]) */ override def length = in.length + out.length + override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Queue[A], B, That]): That = bf match { + case _: Queue.GenericCanBuildFrom[_] => new Queue(in, elem :: out).asInstanceOf[That] + case _ => super.+:(elem)(bf) + } + + override def :+[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Queue[A], B, That]): That = bf match { + case _: Queue.GenericCanBuildFrom[_] => enqueue(elem).asInstanceOf[That] + case _ => super.:+(elem)(bf) + } + /** Creates a new queue with element added at the end * of the old queue. * @@ -119,6 +129,13 @@ class Queue[+A] protected(protected val in: List[A], protected val out: List[A]) case _ => throw new NoSuchElementException("dequeue on empty queue") } + /** Optionally retrieves the first element and a queue of the remaining elements. + * + * @return A tuple of the first element of the queue, and a new queue with this element removed. + * If the queue is empty, `None` is returned. + */ + def dequeueOption: Option[(A, Queue[A])] = if(isEmpty) None else Some(dequeue) + /** Returns the first element in the queue, or throws an error if there * is no element contained in the queue. * diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala index cf05aefe72..9baf3ec179 100644 --- a/src/reflect/scala/reflect/api/BuildUtils.scala +++ b/src/reflect/scala/reflect/api/BuildUtils.scala @@ -122,19 +122,12 @@ private[reflect] trait BuildUtils { self: Universe => def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] } - val SyntacticApply: SyntacticApplyExtractor - - trait SyntacticApplyExtractor { - def apply(tree: Tree, args: List[Tree]): Tree - def unapply(tree: Tree): Some[(Tree, List[Tree])] - } - val SyntacticClassDef: SyntacticClassDefExtractor trait SyntacticClassDefExtractor { - def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], - constrMods: Modifiers, vparamss: List[List[ValDef]], earlyDefs: List[Tree], - parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef + def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], + constrMods: Modifiers, vparamss: List[List[Tree]], earlyDefs: List[Tree], + parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, List[List[ValDef]], List[Tree], List[Tree], ValDef, List[Tree])] } @@ -142,8 +135,8 @@ private[reflect] trait BuildUtils { self: Universe => val SyntacticTraitDef: SyntacticTraitDefExtractor trait SyntacticTraitDefExtractor { - def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], - earlyDefs: List[Tree], parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef + def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], + earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], List[Tree], List[Tree], ValDef, List[Tree])] } @@ -152,7 +145,7 @@ private[reflect] trait BuildUtils { self: Universe => trait SyntacticObjectDefExtractor { def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree], - parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree + parents: List[Tree], selfType: Tree, body: List[Tree]): Tree def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])] } @@ -160,7 +153,7 @@ private[reflect] trait BuildUtils { self: Universe => trait SyntacticPackageObjectDefExtractor { def apply(name: TermName, earlyDefs: List[Tree], - parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree + parents: List[Tree], selfType: Tree, body: List[Tree]): Tree def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])] } @@ -182,7 +175,7 @@ private[reflect] trait BuildUtils { self: Universe => val SyntacticNew: SyntacticNewExtractor trait SyntacticNewExtractor { - def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree + def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] } @@ -196,7 +189,7 @@ private[reflect] trait BuildUtils { self: Universe => val SyntacticFunction: SyntacticFunctionExtractor trait SyntacticFunctionExtractor { - def apply(params: List[ValDef], body: Tree): Tree + def apply(params: List[Tree], body: Tree): Tree def unapply(tree: Tree): Option[(List[ValDef], Tree)] } @@ -204,7 +197,7 @@ private[reflect] trait BuildUtils { self: Universe => val SyntacticDefDef: SyntacticDefDefExtractor trait SyntacticDefDefExtractor { - def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef + def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[List[ValDef]], Tree, Tree)] } @@ -252,5 +245,33 @@ private[reflect] trait BuildUtils { self: Universe => def apply(enums: List[Tree], body: Tree): Tree def unapply(tree: Tree): Option[(List[Tree], Tree)] } + + def UnliftHelper1[T](unliftable: Unliftable[T]): UnliftHelper1[T] + trait UnliftHelper1[T] { + def unapply(lst: List[Tree]): Option[List[T]] + } + + def UnliftHelper2[T](unliftable: Unliftable[T]): UnliftHelper2[T] + trait UnliftHelper2[T] { + def unapply(lst: List[List[Tree]]): Option[List[List[T]]] + } + + val SyntacticMatch: SyntacticMatchExtractor + trait SyntacticMatchExtractor { + def apply(selector: Tree, cases: List[Tree]): Match + def unapply(tree: Match): Option[(Tree, List[CaseDef])] + } + + val SyntacticTry: SyntacticTryExtractor + trait SyntacticTryExtractor { + def apply(block: Tree, catches: List[Tree], finalizer: Tree): Try + def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] + } + + val SyntacticIdent: SyntacticIdentExtractor + trait SyntacticIdentExtractor { + def apply(name: Name, isBackquoted: Boolean = false): Ident + def unapply(tree: Ident): Option[(Name, Boolean)] + } } } diff --git a/src/reflect/scala/reflect/api/Liftable.scala b/src/reflect/scala/reflect/api/Liftable.scala deleted file mode 100644 index 8f6fe066dd..0000000000 --- a/src/reflect/scala/reflect/api/Liftable.scala +++ /dev/null @@ -1,32 +0,0 @@ -package scala.reflect -package api - -trait Liftable[T] { - def apply(universe: api.Universe, value: T): universe.Tree -} - -object Liftable { - private class LiftableConstant[T] extends Liftable[T] { - def apply(universe: Universe, value: T): universe.Tree = - universe.Literal(universe.Constant(value)) - } - - implicit lazy val liftByte: Liftable[Byte] = new LiftableConstant[Byte] - implicit lazy val liftShort: Liftable[Short] = new LiftableConstant[Short] - implicit lazy val liftChar: Liftable[Char] = new LiftableConstant[Char] - implicit lazy val liftInt: Liftable[Int] = new LiftableConstant[Int] - implicit lazy val liftLong: Liftable[Long] = new LiftableConstant[Long] - implicit lazy val liftFloat: Liftable[Float] = new LiftableConstant[Float] - implicit lazy val liftDouble: Liftable[Double] = new LiftableConstant[Double] - implicit lazy val liftBoolean: Liftable[Boolean] = new LiftableConstant[Boolean] - implicit lazy val liftString: Liftable[String] = new LiftableConstant[String] - implicit lazy val liftUnit: Liftable[Unit] = new LiftableConstant[Unit] - - implicit lazy val liftScalaSymbol: Liftable[scala.Symbol] = new Liftable[scala.Symbol] { - def apply(universe: Universe, value: scala.Symbol): universe.Tree = { - import universe._ - val symbol = Select(Ident(TermName("scala")), TermName("Symbol")) - Apply(symbol, List(Literal(Constant(value.name)))) - } - } -} diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala index ecea550225..57464459be 100644 --- a/src/reflect/scala/reflect/api/StandardLiftables.scala +++ b/src/reflect/scala/reflect/api/StandardLiftables.scala @@ -2,35 +2,225 @@ package scala.reflect package api trait StandardLiftables { self: Universe => + import build.{SyntacticTuple, ScalaDot} - private def requireSameUniverse[T](universe: Universe, tp: String, value: T) = - require(universe eq self, s"Can't lift $tp ${showRaw(value)} from universe ${showRaw(universe)} using lift$tp defined for ${showRaw(self)}.") + trait Liftable[T] { + def apply(value: T): Tree + } + + object Liftable { + def apply[T](f: T => Tree): Liftable[T] = + new Liftable[T] { def apply(value: T): Tree = f(value) } + + private def lift[T: Liftable](value: T): Tree = implicitly[Liftable[T]].apply(value) + private def selectScala(names: Name*) = names.tail.foldLeft(ScalaDot(names.head)) { Select(_, _) } + private def callScala(names: Name*)(args: List[Tree]) = Apply(selectScala(names: _*), args) + private def callCollection(name: Name)(args: List[Tree]) = callScala(nme.collection, nme.immutable, name)(args) + private def liftAsLiteral[T]: Liftable[T] = Liftable { v => Literal(Constant(v)) } + + implicit def liftByte[T <: Byte]: Liftable[T] = liftAsLiteral[T] + implicit def liftShort[T <: Short]: Liftable[T] = liftAsLiteral[T] + implicit def liftChar[T <: Char]: Liftable[T] = liftAsLiteral[T] + implicit def liftInt[T <: Int]: Liftable[T] = liftAsLiteral[T] + implicit def liftLong[T <: Long]: Liftable[T] = liftAsLiteral[T] + implicit def liftFloat[T <: Float]: Liftable[T] = liftAsLiteral[T] + implicit def liftDouble[T <: Double]: Liftable[T] = liftAsLiteral[T] + implicit def liftBoolean: Liftable[Boolean] = liftAsLiteral[Boolean] + implicit def liftUnit: Liftable[Unit] = liftAsLiteral[Unit] + implicit def liftString: Liftable[String] = liftAsLiteral[String] - implicit def liftExpr[T <: Expr[_]]: Liftable[T] = new Liftable[T] { - def apply(universe: Universe, value: T): universe.Tree = { - requireSameUniverse(universe, "Expr", value) - value.tree.asInstanceOf[universe.Tree] + implicit def liftScalaSymbol: Liftable[scala.Symbol] = Liftable { v => + callScala(nme.Symbol)(Literal(Constant(v.name)) :: Nil) } - } - implicit def liftType[T <: Type]: Liftable[T] = new Liftable[T] { - def apply(universe: Universe, value: T): universe.Tree = { - requireSameUniverse(universe, "Type", value) - universe.TypeTree(value.asInstanceOf[universe.Type]) + implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) } + implicit def liftExpr[T <: Expr[_]]: Liftable[T] = Liftable { expr => expr.tree } + implicit def liftType[T <: Type]: Liftable[T] = Liftable { tpe => TypeTree(tpe) } + implicit def liftTypeTag[T <: WeakTypeTag[_]]: Liftable[T] = Liftable { ttag => TypeTree(ttag.tpe) } + implicit def liftConstant[T <: Constant]: Liftable[T] = Liftable { const => Literal(const) } + + implicit def liftArray[T: Liftable]: Liftable[Array[T]] = Liftable { arr => callScala(nme.Array)(arr.map(lift(_)).toList) } + implicit def liftVector[T: Liftable]: Liftable[Vector[T]] = Liftable { vect => callCollection(nme.Vector)(vect.map(lift(_)).toList) } + implicit def liftList[T: Liftable]: Liftable[List[T]] = Liftable { lst => callCollection(nme.List)(lst.map(lift(_))) } + implicit def liftMap[K: Liftable, V: Liftable]: Liftable[Map[K, V]] = Liftable { m => callCollection(nme.Map)(m.toList.map(lift(_))) } + implicit def liftSet[T: Liftable]: Liftable[Set[T]] = Liftable { s => callCollection(nme.Set)(s.toList.map(lift(_))) } + + implicit def liftOption[T: Liftable]: Liftable[Option[T]] = Liftable { + case Some(v) => callScala(nme.Some)(lift(v) :: Nil) + case None => selectScala(nme.None) + } + implicit def liftEither[L: Liftable, R: Liftable]: Liftable[Either[L, R]] = Liftable { + case Left(l) => callScala(nme.util, nme.Left)(lift(l) :: Nil) + case Right(r) => callScala(nme.util, nme.Right)(lift(r) :: Nil) } - } - implicit def liftTypeTag[T <: WeakTypeTag[_]]: Liftable[T] = new Liftable[T] { - def apply(universe: Universe, value: T): universe.Tree = { - requireSameUniverse(universe, "TypeTag", value) - universe.TypeTree(value.asInstanceOf[universe.WeakTypeTag[_]].tpe) + implicit def liftTuple1[T1](implicit liftT1: Liftable[T1]): Liftable[Tuple1[T1]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: Nil) + } + implicit def liftTuple2[T1, T2](implicit liftT1: Liftable[T1], liftT2: Liftable[T2]): Liftable[Tuple2[T1, T2]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: Nil) + } + implicit def liftTuple3[T1, T2, T3](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3]): Liftable[Tuple3[T1, T2, T3]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: Nil) + } + implicit def liftTuple4[T1, T2, T3, T4](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4]): Liftable[Tuple4[T1, T2, T3, T4]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: Nil) + } + implicit def liftTuple5[T1, T2, T3, T4, T5](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5]): Liftable[Tuple5[T1, T2, T3, T4, T5]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: Nil) + } + implicit def liftTuple6[T1, T2, T3, T4, T5, T6](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6]): Liftable[Tuple6[T1, T2, T3, T4, T5, T6]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: Nil) + } + implicit def liftTuple7[T1, T2, T3, T4, T5, T6, T7](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7]): Liftable[Tuple7[T1, T2, T3, T4, T5, T6, T7]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: Nil) + } + implicit def liftTuple8[T1, T2, T3, T4, T5, T6, T7, T8](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8]): Liftable[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: Nil) + } + implicit def liftTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9]): Liftable[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: Nil) + } + implicit def liftTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10]): Liftable[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: Nil) + } + implicit def liftTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11]): Liftable[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: Nil) + } + implicit def liftTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12]): Liftable[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: Nil) + } + implicit def liftTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13]): Liftable[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: Nil) + } + implicit def liftTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14]): Liftable[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: Nil) + } + implicit def liftTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15]): Liftable[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: Nil) + } + implicit def liftTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16]): Liftable[Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: Nil) + } + implicit def liftTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17]): Liftable[Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: Nil) + } + implicit def liftTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18]): Liftable[Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: Nil) + } + implicit def liftTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19]): Liftable[Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: Nil) + } + implicit def liftTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19], liftT20: Liftable[T20]): Liftable[Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: liftT20(t._20) :: Nil) + } + implicit def liftTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19], liftT20: Liftable[T20], liftT21: Liftable[T21]): Liftable[Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: liftT20(t._20) :: liftT21(t._21) :: Nil) + } + implicit def liftTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19], liftT20: Liftable[T20], liftT21: Liftable[T21], liftT22: Liftable[T22]): Liftable[Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] = Liftable { t => + SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: liftT20(t._20) :: liftT21(t._21) :: liftT22(t._22) :: Nil) } } - implicit def liftConstant[T <: Constant]: Liftable[T] = new Liftable[T] { - def apply(universe: Universe, value: T): universe.Tree = { - requireSameUniverse(universe, "Constant", value) - universe.Literal(value.asInstanceOf[universe.Constant]) + trait Unliftable[T] { + def unapply(tree: Tree): Option[T] + } + + object Unliftable { + def apply[T](pf: PartialFunction[Tree, T]): Unliftable[T] = new Unliftable[T] { + def unapply(value: Tree): Option[T] = pf.lift(value) + } + + private def unliftPrimitive[Unboxed: ClassTag, Boxed: ClassTag] = Unliftable[Unboxed] { + case Literal(Constant(value)) + if value.getClass == implicitly[ClassTag[Boxed]].runtimeClass + || value.getClass == implicitly[ClassTag[Unboxed]].runtimeClass => + value.asInstanceOf[Unboxed] + } + implicit def unliftByte: Unliftable[Byte] = unliftPrimitive[Byte, java.lang.Byte] + implicit def unliftShort: Unliftable[Short] = unliftPrimitive[Short, java.lang.Short] + implicit def unliftChar: Unliftable[Char] = unliftPrimitive[Char, java.lang.Character] + implicit def unliftInt: Unliftable[Int] = unliftPrimitive[Int, java.lang.Integer] + implicit def unliftLong: Unliftable[Long] = unliftPrimitive[Long, java.lang.Long] + implicit def unliftFloat: Unliftable[Float] = unliftPrimitive[Float, java.lang.Float] + implicit def unliftDouble: Unliftable[Double] = unliftPrimitive[Double, java.lang.Double] + implicit def unliftBoolean: Unliftable[Boolean] = unliftPrimitive[Boolean, java.lang.Boolean] + implicit def unliftUnit: Unliftable[Unit] = unliftPrimitive[Unit, scala.runtime.BoxedUnit] + implicit def unliftString: Unliftable[String] = Unliftable { case Literal(Constant(s: String)) => s } + + implicit def unliftScalaSymbol: Unliftable[scala.Symbol] = Unliftable { + case Apply(ScalaDot(nme.Symbol), List(Literal(Constant(name: String)))) => scala.Symbol(name) + } + + implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(nme.WILDCARD)) => name} + implicit def unliftType: Unliftable[Type] = Unliftable[Type] { case tt: TypeTree if tt.tpe != null => tt.tpe } + implicit def unliftConstant: Unliftable[Constant] = Unliftable[Constant] { case Literal(const) => const } + + implicit def unliftTuple1[T1](implicit UnliftT1: Unliftable[T1]): Unliftable[Tuple1[T1]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: Nil) => Tuple1(v1) + } + implicit def unliftTuple2[T1, T2](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2]): Unliftable[Tuple2[T1, T2]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: Nil) => Tuple2(v1, v2) + } + implicit def unliftTuple3[T1, T2, T3](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3]): Unliftable[Tuple3[T1, T2, T3]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: Nil) => Tuple3(v1, v2, v3) + } + implicit def unliftTuple4[T1, T2, T3, T4](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4]): Unliftable[Tuple4[T1, T2, T3, T4]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: Nil) => Tuple4(v1, v2, v3, v4) + } + implicit def unliftTuple5[T1, T2, T3, T4, T5](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5]): Unliftable[Tuple5[T1, T2, T3, T4, T5]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: Nil) => Tuple5(v1, v2, v3, v4, v5) + } + implicit def unliftTuple6[T1, T2, T3, T4, T5, T6](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6]): Unliftable[Tuple6[T1, T2, T3, T4, T5, T6]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: Nil) => Tuple6(v1, v2, v3, v4, v5, v6) + } + implicit def unliftTuple7[T1, T2, T3, T4, T5, T6, T7](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7]): Unliftable[Tuple7[T1, T2, T3, T4, T5, T6, T7]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: Nil) => Tuple7(v1, v2, v3, v4, v5, v6, v7) + } + implicit def unliftTuple8[T1, T2, T3, T4, T5, T6, T7, T8](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8]): Unliftable[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: Nil) => Tuple8(v1, v2, v3, v4, v5, v6, v7, v8) + } + implicit def unliftTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9]): Unliftable[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: Nil) => Tuple9(v1, v2, v3, v4, v5, v6, v7, v8, v9) + } + implicit def unliftTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10]): Unliftable[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: Nil) => Tuple10(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) + } + implicit def unliftTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11]): Unliftable[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: Nil) => Tuple11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) + } + implicit def unliftTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12]): Unliftable[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: Nil) => Tuple12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) + } + implicit def unliftTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13]): Unliftable[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: Nil) => Tuple13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) + } + implicit def unliftTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14]): Unliftable[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: Nil) => Tuple14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) + } + implicit def unliftTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15]): Unliftable[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: Nil) => Tuple15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) + } + implicit def unliftTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16]): Unliftable[Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: Nil) => Tuple16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) + } + implicit def unliftTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17]): Unliftable[Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: Nil) => Tuple17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) + } + implicit def unliftTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18]): Unliftable[Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: Nil) => Tuple18(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) + } + implicit def unliftTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19]): Unliftable[Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: Nil) => Tuple19(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) + } + implicit def unliftTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19], UnliftT20: Unliftable[T20]): Unliftable[Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: UnliftT20(v20) :: Nil) => Tuple20(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) + } + implicit def unliftTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19], UnliftT20: Unliftable[T20], UnliftT21: Unliftable[T21]): Unliftable[Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: UnliftT20(v20) :: UnliftT21(v21) :: Nil) => Tuple21(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) + } + implicit def unliftTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19], UnliftT20: Unliftable[T20], UnliftT21: Unliftable[T21], UnliftT22: Unliftable[T22]): Unliftable[Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] = Unliftable { + case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: UnliftT20(v20) :: UnliftT21(v21) :: UnliftT22(v22) :: Nil) => Tuple22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) } } } diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala index aec5f19fa0..4ea6ddc7f8 100644 --- a/src/reflect/scala/reflect/api/StandardNames.scala +++ b/src/reflect/scala/reflect/api/StandardNames.scala @@ -96,6 +96,20 @@ trait StandardNames { * of non-private vals and vars are renamed using `LOCAL_SUFFIX_STRING`. */ val LOCAL_SUFFIX_STRING: String + + protected[reflect] val Array: NameType + protected[reflect] val collection: NameType + protected[reflect] val immutable: NameType + protected[reflect] val Left: NameType + protected[reflect] val List: NameType + protected[reflect] val Map: NameType + protected[reflect] val None: NameType + protected[reflect] val Right: NameType + protected[reflect] val Set: NameType + protected[reflect] val Some: NameType + protected[reflect] val Symbol: NameType + protected[reflect] val util: NameType + protected[reflect] val Vector: NameType } /** Defines standard type names that can be accessed via the [[tpnme]] member. diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index 8fc1869dd2..13c2268227 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -71,12 +71,16 @@ trait BuildUtils { self: SymbolTable => def mkAnnotation(trees: List[Tree]): List[Tree] = trees.map(mkAnnotation) - def mkVparamss(argss: List[List[ValDef]]): List[List[ValDef]] = argss.map(_.map(mkParam)) + def mkVparamss(argss: List[List[Tree]]): List[List[ValDef]] = argss.map(_.map(mkParam)) - def mkParam(vd: ValDef): ValDef = { - var newmods = (vd.mods | PARAM) & (~DEFERRED) - if (vd.rhs.nonEmpty) newmods |= DEFAULTPARAM - copyValDef(vd)(mods = newmods) + def mkParam(tree: Tree): ValDef = tree match { + case vd: ValDef => + var newmods = (vd.mods | PARAM) & (~DEFERRED) + if (vd.rhs.nonEmpty) newmods |= DEFAULTPARAM + copyValDef(vd)(mods = newmods) + case _ => + throw new IllegalArgumentException(s"$tree is not valid represenation of function parameter, " + + """consider reformatting it into q"val $name: $T = $default" shape""") } def mkTparams(tparams: List[Tree]): List[TypeDef] = @@ -159,18 +163,11 @@ trait BuildUtils { self: SymbolTable => def apply(tree: Tree, argss: List[List[Tree]]): Tree = argss.foldLeft(tree) { (f, args) => Apply(f, args.map(treeInfo.assignmentToMaybeNamedArg)) } - def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] = { - val treeInfo.Applied(fun, targs, argss) = tree - Some((SyntacticTypeApplied(fun, targs), argss)) - } - } - - object SyntacticApply extends SyntacticApplyExtractor { - def apply(tree: Tree, args: List[Tree]): Tree = SyntacticApplied(tree, List(args)) - - def unapply(tree: Tree): Some[(Tree, List[Tree])] = tree match { - case Apply(fun, args) => Some((fun, args)) - case other => Some((other, Nil)) + def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] = tree match { + case UnApply(treeInfo.Unapplied(Select(fun, nme.unapply)), pats) => + Some((fun, pats :: Nil)) + case treeInfo.Applied(fun, targs, argss) => + Some((SyntacticTypeApplied(fun, targs), argss)) } } @@ -215,24 +212,41 @@ trait BuildUtils { self: SymbolTable => case Nil :: (tail @ ((head :: _) :: _)) if head.mods.isImplicit => tail case other => other } - // undo flag modifications by mergeing flag info from constructor args and fieldDefs + // undo flag modifications by merging flag info from constructor args and fieldDefs val modsMap = fieldDefs.map { case ValDef(mods, name, _, _) => name -> mods }.toMap - val vparamss = mmap(vparamssRestoredImplicits) { vd => - val originalMods = modsMap(vd.name) | (vd.mods.flags & DEFAULTPARAM) - atPos(vd.pos)(ValDef(originalMods, vd.name, vd.tpt, vd.rhs)) + def ctorArgsCorrespondToFields = vparamssRestoredImplicits.flatten.forall { vd => modsMap.contains(vd.name) } + if (!ctorArgsCorrespondToFields) None + else { + val vparamss = mmap(vparamssRestoredImplicits) { vd => + val originalMods = modsMap(vd.name) | (vd.mods.flags & DEFAULTPARAM) + atPos(vd.pos)(ValDef(originalMods, vd.name, vd.tpt, vd.rhs)) + } + result(ctorMods, vparamss, edefs, body) } - result(ctorMods, vparamss, edefs, body) } } } } + protected def mkSelfType(tree: Tree) = tree match { + case vd: ValDef => + require(vd.rhs.isEmpty, "self types must have empty right hand side") + copyValDef(vd)(mods = (vd.mods | PRIVATE) & (~DEFERRED)) + case _ => + throw new IllegalArgumentException(s"$tree is not a valid representation of self type, " + + """consider reformatting into q"val $self: $T" shape""") + } + object SyntacticClassDef extends SyntacticClassDefExtractor { - def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], - constrMods: Modifiers, vparamss: List[List[ValDef]], earlyDefs: List[Tree], - parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef = { + def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], + constrMods: Modifiers, vparamss: List[List[Tree]], earlyDefs: List[Tree], + parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef = { val extraFlags = PARAMACCESSOR | (if (mods.isCase) CASEACCESSOR else 0L) - val vparamss0 = vparamss.map { _.map { vd => copyValDef(vd)(mods = (vd.mods | extraFlags) & (~DEFERRED)) } } + val vparamss0 = vparamss.map { _.map { + case vd: ValDef => copyValDef(vd)(mods = (vd.mods | extraFlags) & (~DEFERRED)) + case tree => throw new IllegalArgumentException(s"$tree is not valid representation of class parameter, " + + """consider reformatting it into q"val $name: $T = $default" shape""") + } } val tparams0 = mkTparams(tparams) val parents0 = gen.mkParents(mods, if (mods.isCase) parents.filter { @@ -241,7 +255,8 @@ trait BuildUtils { self: SymbolTable => } else parents ) val body0 = earlyDefs ::: body - val templ = gen.mkTemplate(parents0, selfType, constrMods, vparamss0, body0) + val selfType0 = mkSelfType(selfType) + val templ = gen.mkTemplate(parents0, selfType0, constrMods, vparamss0, body0) gen.mkClassDef(mods, name, tparams0, templ) } @@ -256,10 +271,10 @@ trait BuildUtils { self: SymbolTable => } object SyntacticTraitDef extends SyntacticTraitDefExtractor { - def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], earlyDefs: List[Tree], - parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef = { + def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], earlyDefs: List[Tree], + parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef = { val mods0 = mods | TRAIT | ABSTRACT - val templ = gen.mkTemplate(parents, selfType, Modifiers(TRAIT), Nil, earlyDefs ::: body) + val templ = gen.mkTemplate(parents, mkSelfType(selfType), Modifiers(TRAIT), Nil, earlyDefs ::: body) gen.mkClassDef(mods0, name, mkTparams(tparams), templ) } @@ -274,8 +289,8 @@ trait BuildUtils { self: SymbolTable => object SyntacticObjectDef extends SyntacticObjectDefExtractor { def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree], - parents: List[Tree], selfType: ValDef, body: List[Tree]) = - ModuleDef(mods, name, gen.mkTemplate(parents, selfType, NoMods, Nil, earlyDefs ::: body)) + parents: List[Tree], selfType: Tree, body: List[Tree]) = + ModuleDef(mods, name, gen.mkTemplate(parents, mkSelfType(selfType), NoMods, Nil, earlyDefs ::: body)) def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])] = tree match { case ModuleDef(mods, name, UnMkTemplate(parents, selfType, _, _, earlyDefs, body)) => @@ -287,7 +302,7 @@ trait BuildUtils { self: SymbolTable => object SyntacticPackageObjectDef extends SyntacticPackageObjectDefExtractor { def apply(name: TermName, earlyDefs: List[Tree], - parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree = + parents: List[Tree], selfType: Tree, body: List[Tree]): Tree = gen.mkPackageObject(SyntacticObjectDef(NoMods, name, earlyDefs, parents, selfType, body)) def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])] = tree match { @@ -377,11 +392,9 @@ trait BuildUtils { self: SymbolTable => } object SyntacticFunction extends SyntacticFunctionExtractor { - def apply(params: List[ValDef], body: Tree): Tree = { - val params0 = params.map { arg => - require(arg.rhs.isEmpty, "anonymous functions don't support default values") - mkParam(arg) - } + def apply(params: List[Tree], body: Tree): Tree = { + val params0 :: Nil = mkVparamss(params :: Nil) + require(params0.forall { _.rhs.isEmpty }, "anonymous functions don't support parameters with default values") Function(params0, body) } @@ -392,8 +405,8 @@ trait BuildUtils { self: SymbolTable => } object SyntacticNew extends SyntacticNewExtractor { - def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree = - gen.mkNew(parents, selfType, earlyDefs ::: body, NoPosition, NoPosition) + def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree = + gen.mkNew(parents, mkSelfType(selfType), earlyDefs ::: body, NoPosition, NoPosition) def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match { case SyntacticApplied(Select(New(SyntacticTypeApplied(ident, targs)), nme.CONSTRUCTOR), argss) => @@ -407,7 +420,7 @@ trait BuildUtils { self: SymbolTable => } object SyntacticDefDef extends SyntacticDefDefExtractor { - def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = + def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef = DefDef(mods, name, mkTparams(tparams), mkVparamss(vparamss), tpt, rhs) def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[List[ValDef]], Tree, Tree)] = tree match { @@ -442,6 +455,20 @@ trait BuildUtils { self: SymbolTable => } } + def UnliftHelper1[T](unliftable: Unliftable[T]) = new UnliftHelper1[T] { + def unapply(lst: List[Tree]): Option[List[T]] = { + val unlifted = lst.flatMap { unliftable.unapply(_) } + if (unlifted.length == lst.length) Some(unlifted) else None + } + } + + def UnliftHelper2[T](unliftable: Unliftable[T]) = new UnliftHelper2[T] { + def unapply(lst: List[List[Tree]]): Option[List[List[T]]] = { + val unlifted = lst.map { l => l.flatMap { unliftable.unapply(_) } } + if (unlifted.flatten.length == lst.flatten.length) Some(unlifted) else None + } + } + object SyntacticValFrom extends SyntacticValFromExtractor { def apply(pat: Tree, rhs: Tree): Tree = gen.ValFrom(pat, gen.mkCheckIfRefutable(pat, rhs)) def unapply(tree: Tree): Option[(Tree, Tree)] = tree match { @@ -672,6 +699,30 @@ trait BuildUtils { self: SymbolTable => case annottee => Some(annottee) } } + + protected def mkCases(cases: List[Tree]): List[CaseDef] = cases.map { + case c: CaseDef => c + case tree => throw new IllegalArgumentException("$tree is not valid representation of pattern match case") + } + + object SyntacticMatch extends SyntacticMatchExtractor { + def apply(selector: Tree, cases: List[Tree]) = Match(selector, mkCases(cases)) + def unapply(tree: Match): Option[(Tree, List[CaseDef])] = Match.unapply(tree) + } + + object SyntacticTry extends SyntacticTryExtractor { + def apply(block: Tree, catches: List[Tree], finalizer: Tree) = Try(block, mkCases(catches), finalizer) + def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] = Try.unapply(tree) + } + + object SyntacticIdent extends SyntacticIdentExtractor { + def apply(name: Name, isBackquoted: Boolean) = { + val id = self.Ident(name) + if (isBackquoted) id updateAttachment BackquotedIdentifierAttachment + id + } + def unapply(tree: Ident): Some[(Name, Boolean)] = Some((tree.name, tree.hasAttachment[BackquotedIdentifierAttachment.type])) + } } val build: BuildImpl = new BuildImpl diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 19f06894c8..1fe6f249b8 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -481,7 +481,6 @@ trait Definitions extends api.StandardDefinitions { lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful - lazy val LiftableClass = getClassIfDefined("scala.reflect.api.Liftable") // defined in scala-reflect.jar, so we need to be careful lazy val BlackboxMacroClass = getClassIfDefined("scala.reflect.macros.BlackboxMacro") // defined in scala-reflect.jar, so we need to be careful def BlackboxMacroContextValue = BlackboxMacroClass.map(sym => getMemberValue(sym, nme.c)) @@ -1371,6 +1370,8 @@ trait Definitions extends api.StandardDefinitions { lazy val symbolType = universeMemberType(tpnme.Symbol) lazy val treeType = universeMemberType(tpnme.Tree) lazy val caseDefType = universeMemberType(tpnme.CaseDef) + lazy val liftableType = universeMemberType(tpnme.Liftable) + lazy val unliftableType = universeMemberType(tpnme.Unliftable) lazy val iterableTreeType = appliedType(IterableClass, treeType) lazy val listTreeType = appliedType(ListClass, treeType) lazy val listListTreeType = appliedType(ListClass, listTreeType) diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index 46f241643b..09fd996f39 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -35,4 +35,7 @@ trait StdAttachments { /** Identifies trees are either result or intermidiate value of for loop desugaring. */ case object ForAttachment extends PlainAttachment + + /** Untyped list of subpatterns attached to selector dummy. */ + case class SubpatternsAttachment(patterns: List[Tree]) } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index c26e815df1..5ad2b15e8c 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -124,8 +124,15 @@ trait StdNames { final val AnyRef: NameType = "AnyRef" final val Array: NameType = "Array" final val List: NameType = "List" + final val Left: NameType = "Left" + final val Right: NameType = "Right" + final val Vector: NameType = "Vector" final val Seq: NameType = "Seq" + final val Set: NameType = "Set" + final val Some: NameType = "Some" final val Symbol: NameType = "Symbol" + final val Map: NameType = "Map" + final val None: NameType = "None" final val WeakTypeTag: NameType = "WeakTypeTag" final val TypeTag : NameType = "TypeTag" final val Expr: NameType = "Expr" @@ -239,6 +246,8 @@ trait StdNames { final val Enum: NameType = "Enum" final val Group: NameType = "Group" final val implicitNotFound: NameType = "implicitNotFound" + final val Liftable: NameType = "Liftable" + final val Unliftable: NameType = "Unliftable" final val Name: NameType = "Name" final val Tree: NameType = "Tree" final val TermName: NameType = "TermName" @@ -328,6 +337,7 @@ trait StdNames { val QUASIQUOTE_TUPLE: NameType = "$quasiquote$tuple$" val QUASIQUOTE_CASE: NameType = "$quasiquote$case$" val QUASIQUOTE_FOR_ENUM: NameType = "$quasiquote$for$enum$" + val QUASIQUOTE_UNLIFT_HELPER: String = "$quasiquote$unlift$helper$" val MIXIN_CONSTRUCTOR: NameType = "$init$" val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" val OUTER: NameType = "$outer" @@ -588,7 +598,6 @@ trait StdNames { val Select: NameType = "Select" val SelectFromTypeTree: NameType = "SelectFromTypeTree" val SyntacticApplied: NameType = "SyntacticApplied" - val SyntacticApply: NameType = "SyntacticApply" val SyntacticAssign: NameType = "SyntacticAssign" val SyntacticBlock: NameType = "SyntacticBlock" val SyntacticClassDef: NameType = "SyntacticClassDef" @@ -598,10 +607,13 @@ trait StdNames { val SyntacticForYield: NameType = "SyntacticForYield" val SyntacticFunction: NameType = "SyntacticFunction" val SyntacticFunctionType: NameType = "SyntacticFunctionType" - val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef" - val SyntacticObjectDef: NameType = "SyntacticObjectDef" + val SyntacticIdent: NameType = "SyntacticIdent" + val SyntacticMatch: NameType = "SyntacticMatch" val SyntacticNew: NameType = "SyntacticNew" + val SyntacticObjectDef: NameType = "SyntacticObjectDef" + val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef" val SyntacticTraitDef: NameType = "SyntacticTraitDef" + val SyntacticTry: NameType = "SyntacticTry" val SyntacticTuple: NameType = "SyntacticTuple" val SyntacticTupleType: NameType = "SyntacticTupleType" val SyntacticTypeApplied: NameType = "SyntacticTypeApplied" @@ -751,10 +763,13 @@ trait StdNames { val typedProductIterator: NameType = "typedProductIterator" val TypeName: NameType = "TypeName" val typeTagToManifest: NameType = "typeTagToManifest" + val util: NameType = "util" val unapply: NameType = "unapply" val unapplySeq: NameType = "unapplySeq" val unbox: NameType = "unbox" val universe: NameType = "universe" + val UnliftHelper1: NameType = "UnliftHelper1" + val UnliftHelper2: NameType = "UnliftHelper2" val update: NameType = "update" val updateDynamic: NameType = "updateDynamic" val value: NameType = "value" @@ -784,7 +799,7 @@ trait StdNames { final val STAR : NameType = "*" final val TILDE: NameType = "~" - final val isUnary: Set[Name] = Set(MINUS, PLUS, TILDE, BANG) + final val isUnary: Set[Name] = scala.collection.immutable.Set(MINUS, PLUS, TILDE, BANG) } // value-conversion methods @@ -837,8 +852,8 @@ trait StdNames { val UNARY_! = encode("unary_!") // Grouped here so Cleanup knows what tests to perform. - val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE) - val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames + val CommonOpNames = scala.collection.immutable.Set[Name](OR, XOR, AND, EQ, NE) + val BooleanOpNames = scala.collection.immutable.Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames val add: NameType = "add" val complement: NameType = "complement" diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 85bc3158f6..0dfcf06874 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1379,6 +1379,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => def hasRawInfo: Boolean = infos ne null def hasCompleteInfo = hasRawInfo && rawInfo.isComplete + // does not run adaptToNewRun, which is prone to trigger cycles (SI-8029) + // TODO: give this a better name if you understand the intent of the caller. + // Is it something to do with `reallyExists` or `isStale`? + final def rawInfoIsNoType: Boolean = { + hasRawInfo && (infos.info eq NoType) + } + /** Return info without checking for initialization or completing */ def rawInfo: Type = { var infos = this.infos @@ -2038,7 +2045,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this symbol defined in the same scope and compilation unit as `that` symbol? */ def isCoDefinedWith(that: Symbol) = ( - (this.rawInfo ne NoType) + !rawInfoIsNoType && (this.effectiveOwner == that.effectiveOwner) && ( !this.effectiveOwner.isPackageClass || (this.associatedFile eq NoAbstractFile) @@ -2475,10 +2482,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** String representation, including symbol's kind e.g., "class Foo", "method Bar". * If hasMeaninglessName is true, uses the owner's name to disambiguate identity. */ - override def toString: String = compose( - kindString, - if (hasMeaninglessName) owner.decodedName + idString else nameString - ) + override def toString: String = { + if (isPackageObjectOrClass && !settings.debug) + s"package object ${owner.decodedName}" + else compose( + kindString, + if (hasMeaninglessName) owner.decodedName + idString else nameString + ) + } /** String representation of location. */ diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index a0bd64f850..6269004298 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -16,8 +16,7 @@ abstract class TreeGen extends macros.TreeBuilder { def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name) def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name) def scalaAnnotationDot(name: Name) = Select(scalaDot(nme.annotation), name) - def scalaAnyRefConstrRaw = scalaDot(tpnme.AnyRef) - def scalaAnyRefConstr = scalaAnyRefConstrRaw setSymbol AnyRefClass // used in ide + def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) // used in ide def scalaFunctionConstr(argtpes: List[Tree], restpe: Tree, abstractFun: Boolean = false): Tree = { val cls = if (abstractFun) @@ -393,7 +392,7 @@ abstract class TreeGen extends macros.TreeBuilder { def mkParents(ownerMods: Modifiers, parents: List[Tree], parentPos: Position = NoPosition) = if (ownerMods.isCase) parents ::: List(scalaDot(tpnme.Product), scalaDot(tpnme.Serializable)) - else if (parents.isEmpty) atPos(parentPos)(scalaAnyRefConstrRaw) :: Nil + else if (parents.isEmpty) atPos(parentPos)(scalaAnyRefConstr) :: Nil else parents def mkClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], templ: Template): ClassDef = { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index e483fa6ba8..99e6ae633f 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3392,11 +3392,14 @@ trait Types /** Rebind symbol `sym` to an overriding member in type `pre`. */ private def rebind(pre: Type, sym: Symbol): Symbol = { if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym - else pre.nonPrivateMember(sym.name).suchThat(sym => - // SI-7928 `isModuleNotMethod` is here to avoid crashing with overloaded module accessor and module symbols - // after refchecks eliminates a ModuleDef that implements and interface. - sym.isType || (!sym.isModuleNotMethod && sym.isStable && !sym.hasVolatileType) - ) orElse sym + else pre.nonPrivateMember(sym.name).suchThat { sym => + // SI-7928 `isModuleNotMethod` is here to avoid crashing with spuriously "overloaded" module accessor and module symbols. + // These appear after refchecks eliminates ModuleDefs that implement an interface. + // Here, we exclude the module symbol, which allows us to bind to the accessor. + // SI-8054 We must only do this after refchecks, otherwise we exclude the module symbol which does not yet have an accessor! + val isModuleWithAccessor = phase.refChecked && sym.isModuleNotMethod + sym.isType || (!isModuleWithAccessor && sym.isStable && !sym.hasVolatileType) + } orElse sym } /** Convert a `super` prefix to a this-type if `sym` is abstract or final. */ diff --git a/src/reflect/scala/reflect/internal/util/StringOps.scala b/src/reflect/scala/reflect/internal/util/StringOps.scala index 14f349f502..efb8126ff0 100644 --- a/src/reflect/scala/reflect/internal/util/StringOps.scala +++ b/src/reflect/scala/reflect/internal/util/StringOps.scala @@ -23,12 +23,16 @@ trait StringOps { def oempty(xs: String*) = xs filterNot (x => x == null || x == "") def ojoin(xs: String*): String = oempty(xs: _*) mkString " " def longestCommonPrefix(xs: List[String]): String = xs match { - case Nil => "" - case xs if xs contains "" => "" - case x :: xs => - val ch = x charAt 0 - if (xs exists (_.head != ch)) "" - else "" + ch + longestCommonPrefix(xs map (_ substring 1)) + case Nil => "" + case w :: Nil => w + case _ => + def lcp(ss: List[String]): String = { + val w :: ws = ss + if (w == "") "" + else if (ws exists (s => s == "" || (s charAt 0) != (w charAt 0))) "" + else w.substring(0, 1) + lcp(ss map (_ substring 1)) + } + lcp(xs) } /** Like String#trim, but trailing whitespace only. */ diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 344f7682c1..0f41506382 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -57,6 +57,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.CompoundTypeTreeOriginalAttachment this.BackquotedIdentifierAttachment this.ForAttachment + this.SubpatternsAttachment this.noPrint this.typeDebug // inaccessible: this.maxFree @@ -204,6 +205,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.TermName this.TypeName this.BooleanFlag + this.Liftable + this.Unliftable this.WeakTypeTag this.TypeTag this.Expr @@ -315,7 +318,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.MirrorClass definitions.TypeCreatorClass definitions.TreeCreatorClass - definitions.LiftableClass definitions.BlackboxMacroClass definitions.WhiteboxMacroClass definitions.BlackboxContextClass diff --git a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala index 1b3d60d41a..53c7c82e89 100644 --- a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala +++ b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala @@ -294,7 +294,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput // This is jline's entry point for completion. override def complete(buf: String, cursor: Int): Candidates = { verbosity = if (isConsecutiveTabs(buf, cursor)) verbosity + 1 else 0 - repldbg("\ncomplete(%s, %d) last = (%s, %d), verbosity: %s".format(buf, cursor, lastBuf, lastCursor, verbosity)) + repldbg(f"%ncomplete($buf, $cursor%d) last = ($lastBuf, $lastCursor%d), verbosity: $verbosity") // we don't try lower priority completions unless higher ones return no results. def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Candidates] = { @@ -307,8 +307,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput val advance = longestCommonPrefix(winners) lastCursor = p.position + advance.length lastBuf = (buf take p.position) + advance - repldbg("tryCompletion(%s, _) lastBuf = %s, lastCursor = %s, p.position = %s".format( - p, lastBuf, lastCursor, p.position)) + repldbg(s"tryCompletion($p, _) lastBuf = $lastBuf, lastCursor = $lastCursor, p.position = ${p.position}") p.position } diff --git a/src/swing/scala/swing/Publisher.scala b/src/swing/scala/swing/Publisher.scala index 96207de808..578ef71e09 100644 --- a/src/swing/scala/swing/Publisher.scala +++ b/src/swing/scala/swing/Publisher.scala @@ -44,7 +44,7 @@ trait Publisher extends Reactor { /** * Notify all registered reactions. */ - def publish(e: Event) { for (l <- listeners) l(e) } + def publish(e: Event) { for (l <- listeners) if (l.isDefinedAt(e)) l(e) } listenTo(this) } diff --git a/test/files/instrumented/InstrumentationTest.check b/test/files/instrumented/InstrumentationTest.check index 0c570fa12c..c82d16bd34 100644 --- a/test/files/instrumented/InstrumentationTest.check +++ b/test/files/instrumented/InstrumentationTest.check @@ -1,3 +1,4 @@ +#partest !avian true Method call statistics: 1 Foo1.<init>()V @@ -8,3 +9,6 @@ Method call statistics: 1 scala/Predef$.println(Ljava/lang/Object;)V 1 scala/io/AnsiColor$class.$init$(Lscala/io/AnsiColor;)V 1 scala/runtime/BoxesRunTime.boxToBoolean(Z)Ljava/lang/Boolean; +#partest avian +!!!TEST SKIPPED!!! +Instrumentation is not supported on Avian. diff --git a/test/files/instrumented/InstrumentationTest.scala b/test/files/instrumented/InstrumentationTest.scala index 0e53f80857..458fd4974b 100644 --- a/test/files/instrumented/InstrumentationTest.scala +++ b/test/files/instrumented/InstrumentationTest.scala @@ -15,16 +15,21 @@ package instrumented { /** Tests if instrumentation itself works correctly */ object Test { def main(args: Array[String]) { - // force predef initialization before profiling - Predef - startProfiling() - val foo1 = new Foo1 - foo1.someMethod - val foo2 = new instrumented.Foo2 - foo2.someMethod - // should box the boolean - println(true) - stopProfiling() - printStatistics() + if (scala.tools.partest.utils.Properties.isAvian) { + println("!!!TEST SKIPPED!!!") + println("Instrumentation is not supported on Avian.") + } else { + // force predef initialization before profiling + Predef + startProfiling() + val foo1 = new Foo1 + foo1.someMethod + val foo2 = new instrumented.Foo2 + foo2.someMethod + // should box the boolean + println(true) + stopProfiling() + printStatistics() + } } } diff --git a/test/files/instrumented/inline-in-constructors.check b/test/files/instrumented/inline-in-constructors.check index c6c9ae4e15..b58c1d77d5 100644 --- a/test/files/instrumented/inline-in-constructors.check +++ b/test/files/instrumented/inline-in-constructors.check @@ -1,3 +1,7 @@ +#partest !avian Method call statistics: 1 instrumented/Bar.<init>(Z)V 1 instrumented/Foo.<init>(I)V +#partest avian +!!!TEST SKIPPED!!! +Instrumentation is not supported on Avian. diff --git a/test/files/instrumented/inline-in-constructors/test_3.scala b/test/files/instrumented/inline-in-constructors/test_3.scala index c4d4cc5f37..949e9945e7 100644 --- a/test/files/instrumented/inline-in-constructors/test_3.scala +++ b/test/files/instrumented/inline-in-constructors/test_3.scala @@ -3,13 +3,18 @@ import instrumented._ object Test { def main(args: Array[String]) { - // force predef initialization before profiling - Predef - MyPredef - startProfiling() - val a = new Foo(2) - val b = new Bar(true) - stopProfiling() - printStatistics() + if (scala.tools.partest.utils.Properties.isAvian) { + println("!!!TEST SKIPPED!!!") + println("Instrumentation is not supported on Avian.") + } else { + // force predef initialization before profiling + Predef + MyPredef + startProfiling() + val a = new Foo(2) + val b = new Bar(true) + stopProfiling() + printStatistics() + } } } diff --git a/test/files/neg/compile-time-only-a.check b/test/files/neg/compile-time-only-a.check index 1c4c72171f..9bc96f6b9b 100644 --- a/test/files/neg/compile-time-only-a.check +++ b/test/files/neg/compile-time-only-a.check @@ -1,49 +1,79 @@ -compile-time-only-a.scala:9: error: C3 +compile-time-only-a.scala:10: error: C3 @compileTimeOnly("C3") case class C3(x: Int) ^ -compile-time-only-a.scala:11: error: C4 +compile-time-only-a.scala:12: error: C4 @compileTimeOnly("C4") case class C4(x: Int) ^ -compile-time-only-a.scala:16: error: C5 +compile-time-only-a.scala:17: error: C5 implicit class C5(val x: Int) { ^ -compile-time-only-a.scala:28: error: C1 +compile-time-only-a.scala:32: error: C1 new C1() ^ -compile-time-only-a.scala:32: error: C2 +compile-time-only-a.scala:36: error: C2 C2 ^ -compile-time-only-a.scala:34: error: C3 +compile-time-only-a.scala:38: error: C3 new C3(2) ^ -compile-time-only-a.scala:37: error: C4 +compile-time-only-a.scala:41: error: C4 new C4(2) ^ -compile-time-only-a.scala:41: error: C5 +compile-time-only-a.scala:45: error: C5 2.ext ^ -compile-time-only-a.scala:42: error: C5 +compile-time-only-a.scala:46: error: C5 C5(2) ^ -compile-time-only-a.scala:45: error: C6.x +compile-time-only-a.scala:49: error: C6.x val _ = c6.x ^ -compile-time-only-a.scala:46: error: C6.foo +compile-time-only-a.scala:50: error: C6.foo c6.foo ^ -compile-time-only-a.scala:48: error: C6.y +compile-time-only-a.scala:51: error: C6.Foo + type Foo = c6.Foo + ^ +compile-time-only-a.scala:52: error: C6.y c6.y = c6.y ^ -compile-time-only-a.scala:48: error: C6.y +compile-time-only-a.scala:52: error: C6.y c6.y = c6.y ^ -compile-time-only-a.scala:54: error: placebo -@placebo - ^ -compile-time-only-a.scala:56: error: placebo +compile-time-only-a.scala:54: error: C7 + val c701: (C7, C7) = ??? + ^ +compile-time-only-a.scala:55: error: C7 + val c702: (C7 => C7) = ??? + ^ +compile-time-only-a.scala:56: error: C7 + val c703: { val x: C7 } = ??? + ^ +compile-time-only-a.scala:57: error: C7 + val c704: AnyRef with C7 = ??? + ^ +compile-time-only-a.scala:60: error: C7 + val c706: C7 Either C7 = ??? + ^ +compile-time-only-a.scala:61: error: C7 + val c707a: List[C7] = ??? + ^ +compile-time-only-a.scala:63: error: C7 + val c708a: T forSome { type T <: C7 } = ??? + ^ +compile-time-only-a.scala:66: error: C8 + val c709: (C8[Int], C8[C7]) = ??? + ^ +compile-time-only-a.scala:67: error: C8 + val c710: (C8[_] => C8[_]) = ??? + ^ +compile-time-only-a.scala:74: error: placebo +class Test { + ^ +compile-time-only-a.scala:75: error: placebo @placebo def x = (2: @placebo) - ^ -compile-time-only-a.scala:56: error: placebo + ^ +compile-time-only-a.scala:75: error: placebo @placebo def x = (2: @placebo) ^ -16 errors found +26 errors found diff --git a/test/files/neg/compile-time-only-a.scala b/test/files/neg/compile-time-only-a.scala index 43d36dfab1..533175a699 100644 --- a/test/files/neg/compile-time-only-a.scala +++ b/test/files/neg/compile-time-only-a.scala @@ -1,4 +1,5 @@ import scala.annotation.compileTimeOnly +import scala.language.existentials @compileTimeOnly("C1") class C1 object C1 @@ -24,6 +25,9 @@ class C6(@compileTimeOnly("C6.x") val x: Int) { @compileTimeOnly("C6.y") var y = 3 } +@compileTimeOnly("C7") class C7 +@compileTimeOnly("C8") class C8[T] + object Test extends App { new C1() C1 @@ -46,6 +50,21 @@ object Test extends App { c6.foo type Foo = c6.Foo c6.y = c6.y + + val c701: (C7, C7) = ??? + val c702: (C7 => C7) = ??? + val c703: { val x: C7 } = ??? + val c704: AnyRef with C7 = ??? + // https://groups.google.com/forum/#!topic/scala-internals/5n07TiCnBZU + // val c705: ({ @compileTimeOnly("C7") type C7[T] = List[T] })#C7[_] = ??? + val c706: C7 Either C7 = ??? + val c707a: List[C7] = ??? + val c707b = List[C7]() + val c708a: T forSome { type T <: C7 } = ??? + // https://groups.google.com/forum/#!topic/scala-internals/5n07TiCnBZU + // val c708b: T forSome { @compileTimeOnly("C7") type T } = ??? + val c709: (C8[Int], C8[C7]) = ??? + val c710: (C8[_] => C8[_]) = ??? } @compileTimeOnly("placebo") diff --git a/test/files/neg/macro-blackbox-extractor/Macros_1.scala b/test/files/neg/macro-blackbox-extractor/Macros_1.scala index 5c7748bec9..f0bfe53aa2 100644 --- a/test/files/neg/macro-blackbox-extractor/Macros_1.scala +++ b/test/files/neg/macro-blackbox-extractor/Macros_1.scala @@ -2,7 +2,7 @@ import scala.reflect.macros.BlackboxContext import language.experimental.macros object Extractor { - def unapply(x: Int) = macro Macros.unapplyImpl + def unapply(x: Int): Any = macro Macros.unapplyImpl } object Macros { diff --git a/test/files/neg/macro-blackbox-structural/Impls_Macros_1.scala b/test/files/neg/macro-blackbox-structural/Impls_Macros_1.scala index 08f1c21e89..f5e85d57ea 100644 --- a/test/files/neg/macro-blackbox-structural/Impls_Macros_1.scala +++ b/test/files/neg/macro-blackbox-structural/Impls_Macros_1.scala @@ -11,5 +11,5 @@ object Macros { """ } - def foo = macro impl + def foo: Any = macro impl }
\ No newline at end of file diff --git a/test/files/neg/macro-bundle-object.check b/test/files/neg/macro-bundle-object.check index 293f40a178..78e7119fa7 100644 --- a/test/files/neg/macro-bundle-object.check +++ b/test/files/neg/macro-bundle-object.check @@ -1,5 +1,5 @@ macro-bundle-object.scala:10: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext): c.Tree found : : Nothing number of parameter sections differ diff --git a/test/files/neg/macro-invalidret.check b/test/files/neg/macro-invalidret.check index ea003a17ec..6c5baf76b4 100644 --- a/test/files/neg/macro-invalidret.check +++ b/test/files/neg/macro-invalidret.check @@ -12,4 +12,24 @@ Macros_Test_2.scala:3: error: macro implementation has incompatible shape: type mismatch for return type: reflect.runtime.universe.Literal does not conform to c.Expr[Any] def foo2 = macro Impls.foo2 ^ -two errors found +Macros_Test_2.scala:6: error: macro defs must have explicitly specified return types + def foo5 = macro Impls.foo5 + ^ +Macros_Test_2.scala:7: warning: macro defs must have explicitly specified return types (inference of Int from macro impl's c.Expr[Int] is deprecated and is going to stop working in 2.12) + def foo6 = macro Impls.foo6 + ^ +Macros_Test_2.scala:14: error: exception during macro expansion: +scala.NotImplementedError: an implementation is missing + at scala.Predef$.$qmark$qmark$qmark(Predef.scala:227) + at Impls$.foo3(Impls_1.scala:7) + + foo3 + ^ +Macros_Test_2.scala:15: error: macro implementation is missing + foo4 + ^ +Macros_Test_2.scala:17: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses + foo6 + ^ +two warnings found +5 errors found diff --git a/test/files/neg/macro-invalidret.flags b/test/files/neg/macro-invalidret.flags index cd66464f2f..946c53ec0e 100644 --- a/test/files/neg/macro-invalidret.flags +++ b/test/files/neg/macro-invalidret.flags @@ -1 +1,3 @@ --language:experimental.macros
\ No newline at end of file +-language:experimental.macros +-Xfatal-warnings +-deprecation
\ No newline at end of file diff --git a/test/files/neg/macro-invalidret/Impls_1.scala b/test/files/neg/macro-invalidret/Impls_1.scala index d957b74512..b32463899e 100644 --- a/test/files/neg/macro-invalidret/Impls_1.scala +++ b/test/files/neg/macro-invalidret/Impls_1.scala @@ -4,4 +4,7 @@ import scala.reflect.runtime.{universe => ru} object Impls { def foo1(c: BlackboxContext) = 2 def foo2(c: BlackboxContext) = ru.Literal(ru.Constant(42)) + def foo3(c: BlackboxContext) = ??? + def foo5(c: BlackboxContext) = c.universe.Literal(c.universe.Constant(42)) + def foo6(c: BlackboxContext) = c.Expr[Int](c.universe.Literal(c.universe.Constant(42))) } diff --git a/test/files/neg/macro-invalidret/Macros_Test_2.scala b/test/files/neg/macro-invalidret/Macros_Test_2.scala index f8880fa023..8840f492ab 100644 --- a/test/files/neg/macro-invalidret/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidret/Macros_Test_2.scala @@ -1,10 +1,18 @@ object Macros { def foo1 = macro Impls.foo1 def foo2 = macro Impls.foo2 + def foo3 = macro Impls.foo3 + def foo4 = macro ??? + def foo5 = macro Impls.foo5 + def foo6 = macro Impls.foo6 } object Test extends App { import Macros._ foo1 foo2 + foo3 + foo4 + foo5 + foo6 }
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype.check b/test/files/neg/macro-invalidsig-params-badtype.check index 6d72185ff2..d6b5c5521d 100644 --- a/test/files/neg/macro-invalidsig-params-badtype.check +++ b/test/files/neg/macro-invalidsig-params-badtype.check @@ -1,5 +1,5 @@ Impls_Macros_1.scala:8: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree found : (c: scala.reflect.macros.BlackboxContext)(x: Int): Nothing type mismatch for parameter x: c.Expr[Int] does not conform to Int diff --git a/test/files/neg/macro-invalidsig.check b/test/files/neg/macro-invalidsig.check index e09d46146d..5ff4ed18cb 100644 --- a/test/files/neg/macro-invalidsig.check +++ b/test/files/neg/macro-invalidsig.check @@ -1,29 +1,29 @@ Macros_Test_2.scala:2: error: macro implementations cannot have implicit parameters other than WeakTypeTag evidences - def foo[U] = macro Impls1.foo[U] - ^ + def foo[U]: Int = macro Impls1.foo[U] + ^ Macros_Test_2.scala:6: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext): c.Tree found : : Nothing number of parameter sections differ def foo = macro Impls2.foo ^ Macros_Test_2.scala:10: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext): c.Tree found : (c: scala.reflect.api.Universe): Nothing type mismatch for parameter c: scala.reflect.macros.BlackboxContext does not conform to scala.reflect.api.Universe def foo = macro Impls3.foo ^ Macros_Test_2.scala:14: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext): c.Tree found : (cs: scala.reflect.macros.BlackboxContext*): Nothing types incompatible for parameter cs: corresponding is not a vararg parameter def foo = macro Impls4.foo ^ Macros_Test_2.scala:18: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Any]): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Any]): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree found : (c: scala.reflect.macros.BlackboxContext): Nothing number of parameter sections differ @@ -33,35 +33,35 @@ Macros_Test_2.scala:22: error: macro implementations cannot have implicit parame def foo[U](x: Int) = macro Impls6.foo[T, U] ^ Macros_Test_2.scala:26: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree found : (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): Nothing parameter lists have different length, found extra parameter y: c.Expr[Int] def foo(x: Int) = macro Impls7.foo ^ Macros_Test_2.scala:30: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int]): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree): c.Tree found : (c: scala.reflect.macros.BlackboxContext)(x: c.universe.Symbol): Nothing type mismatch for parameter x: c.Expr[Int] does not conform to c.universe.Symbol def foo(x: Int) = macro Impls8.foo ^ Macros_Test_2.scala:34: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree, y: c.Tree): c.Tree found : (c: scala.reflect.macros.BlackboxContext)(xs: c.Expr[Int]*): Nothing parameter lists have different length, required extra parameter y: c.Expr[Int] def foo(x: Int, y: Int) = macro Impls9.foo ^ Macros_Test_2.scala:38: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext)(x: c.Tree, y: c.Tree): c.Tree found : (c: scala.reflect.macros.BlackboxContext)(y: c.Expr[Int], x: c.Expr[Int]): Nothing parameter names differ: x != y def foo(x: Int, y: Int) = macro Impls10.foo ^ Macros_Test_2.scala:42: error: macro implementation has incompatible shape: - required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Any] + required: (c: scala.reflect.macros.BlackboxContext): c.Expr[Nothing] or : (c: scala.reflect.macros.BlackboxContext): c.Tree found : (c: scala.reflect.macros.BlackboxContext)(U: c.universe.Type): Nothing number of parameter sections differ @@ -77,9 +77,9 @@ Macros_Test_2.scala:54: error: macro implementation reference has too few type a def foo = macro Impls14.foo ^ Macros_Test_2.scala:59: error: macro implementation reference has too few type arguments for method foo: [T, U, V](c: scala.reflect.macros.BlackboxContext)(implicit evidence$5: c.WeakTypeTag[T], implicit evidence$6: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] - def foo15[V] = macro Impls15.foo - ^ + def foo15[V]: Unit = macro Impls15.foo + ^ Macros_Test_2.scala:60: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.BlackboxContext)(implicit evidence$7: c.WeakTypeTag[T], implicit evidence$8: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] - def foo16[V] = macro Impls16.foo[V] - ^ + def foo16[V]: Unit = macro Impls16.foo[V] + ^ 16 errors found diff --git a/test/files/neg/macro-invalidsig/Macros_Test_2.scala b/test/files/neg/macro-invalidsig/Macros_Test_2.scala index 0a6a321431..89a5302d8a 100644 --- a/test/files/neg/macro-invalidsig/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidsig/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros1 { - def foo[U] = macro Impls1.foo[U] + def foo[U]: Int = macro Impls1.foo[U] } object Macros2 { @@ -56,8 +56,8 @@ object Macros14 { class D[T] { class C[U] { - def foo15[V] = macro Impls15.foo - def foo16[V] = macro Impls16.foo[V] + def foo15[V]: Unit = macro Impls15.foo + def foo16[V]: Unit = macro Impls16.foo[V] } } diff --git a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala index 0b3ca0590b..cf8accf94f 100644 --- a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala @@ -1,4 +1,4 @@ -object Macros { def foo(x: Int) = macro Impls.foo } +object Macros { def foo(x: Int): Int = macro Impls.foo } import Macros._ object Test extends App { diff --git a/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala index 3139599108..76397701f9 100644 --- a/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo[U <: String] = macro Impls.foo[U] + def foo[U <: String]: Unit = macro Impls.foo[U] } object Test extends App { diff --git a/test/files/neg/macro-invalidusage-badtargs.check b/test/files/neg/macro-invalidusage-badtargs.check index 6a9e1d6e6b..722ec03765 100644 --- a/test/files/neg/macro-invalidusage-badtargs.check +++ b/test/files/neg/macro-invalidusage-badtargs.check @@ -1,16 +1,16 @@ -Macros_Test_2.scala:11: error: macro method foo1: (x: Int)Int does not take type parameters. +Macros_Test_2.scala:13: error: macro method foo1: (x: Int)Int does not take type parameters. foo1[String](42) ^ -Macros_Test_2.scala:12: error: wrong number of type parameters for macro method foo2: [T](x: Int)Int +Macros_Test_2.scala:14: error: wrong number of type parameters for macro method foo2: [T](x: Int)Int foo2[String, String](42) ^ -Macros_Test_2.scala:13: error: wrong number of type parameters for macro method foo3: [T, U](x: Int)Int +Macros_Test_2.scala:15: error: wrong number of type parameters for macro method foo3: [T, U](x: Int)Int foo3[String](42) ^ -Macros_Test_2.scala:14: error: String takes no type parameters, expected: one +Macros_Test_2.scala:16: error: String takes no type parameters, expected: one foo4[String](42) ^ -Macros_Test_2.scala:15: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T). +Macros_Test_2.scala:17: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T). List's type parameters do not match type T's expected parameters: type A has no type parameters, but type U has one foo5[List](42) diff --git a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala index fd16d163c3..47e51bbf44 100644 --- a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala @@ -1,9 +1,11 @@ +import scala.language.higherKinds + object Macros { - def foo1(x: Int) = macro Impls.foo - def foo2[T](x: Int) = macro Impls.foo - def foo3[T, U](x: Int) = macro Impls.foo - def foo4[T[_]](x: Int) = macro Impls.foo - def foo5[T[U[_]]](x: Int) = macro Impls.foo + def foo1(x: Int): Int = macro Impls.foo + def foo2[T](x: Int): Int = macro Impls.foo + def foo3[T, U](x: Int): Int = macro Impls.foo + def foo4[T[_]](x: Int): Int = macro Impls.foo + def foo5[T[U[_]]](x: Int): Int = macro Impls.foo } object Test extends App { diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala index 343cec99b5..578aa45867 100644 --- a/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.check b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check index 8c8f039225..6b5d3013ba 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-a.check +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check @@ -1,5 +1,5 @@ Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; macro method foo cannot be used here - term macros cannot override abstract methods - def foo(x: Int) = macro Impls.impl + def foo(x: Int): Int = macro Impls.impl ^ one error found diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala index 0e8a5f3b01..9c05db83e3 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala @@ -9,5 +9,5 @@ trait Foo { } object Macros extends Foo { - def foo(x: Int) = macro Impls.impl + def foo(x: Int): Int = macro Impls.impl } diff --git a/test/files/neg/macro-override-method-overrides-macro.check b/test/files/neg/macro-override-method-overrides-macro.check index e8cba5d029..e396d65ff1 100644 --- a/test/files/neg/macro-override-method-overrides-macro.check +++ b/test/files/neg/macro-override-method-overrides-macro.check @@ -1,5 +1,5 @@ Macros_Test_2.scala:8: error: overriding macro method foo in class B of type (x: String)Unit; method foo cannot be used here - only term macros can override term macros - override def foo(x: String) = println("fooDString") + override def foo(x: String): Unit = println("fooDString") ^ one error found diff --git a/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala index 36821b05d8..d47157766e 100644 --- a/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala +++ b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala @@ -1,15 +1,15 @@ class B { - def foo(x: String) = macro Impls.fooBString - def foo(x: Int) = macro Impls.fooBInt - def foo(x: Boolean) = println("fooBBoolean") + def foo(x: String): Unit = macro Impls.fooBString + def foo(x: Int): Unit = macro Impls.fooBInt + def foo(x: Boolean): Unit = println("fooBBoolean") } class D extends B { - override def foo(x: String) = println("fooDString") - override def foo(x: Int) = macro Impls.fooDInt + override def foo(x: String): Unit = println("fooDString") + override def foo(x: Int): Unit = macro Impls.fooDInt } class Z extends D { - override def foo(x: String) = macro Impls.fooZString - override def foo(x: Boolean) = println("fooZBoolean") + override def foo(x: String): Unit = macro Impls.fooZString + override def foo(x: Boolean): Unit = println("fooZBoolean") } diff --git a/test/files/neg/macro-quasiquotes.check b/test/files/neg/macro-quasiquotes.check index 338ad42b23..c690b61fe1 100644 --- a/test/files/neg/macro-quasiquotes.check +++ b/test/files/neg/macro-quasiquotes.check @@ -1,8 +1,8 @@ Macros_1.scala:14: error: macro implementation has incompatible shape: - required: (x: Impls.this.c.Expr[Int]): Impls.this.c.Expr[Any] + required: (x: Impls.this.c.Expr[Int]): Impls.this.c.Expr[Unit] or : (x: Impls.this.c.Tree): Impls.this.c.Tree found : (x: Impls.this.c.universe.Block): Impls.this.c.Tree type mismatch for parameter x: Impls.this.c.Expr[Int] does not conform to Impls.this.c.universe.Block - def m3(x: Int) = macro Impls.impl3 - ^ + def m3(x: Int): Unit = macro Impls.impl3 + ^ one error found diff --git a/test/files/neg/macro-quasiquotes/Macros_1.scala b/test/files/neg/macro-quasiquotes/Macros_1.scala index 7f0219e6ac..098e4b3b92 100644 --- a/test/files/neg/macro-quasiquotes/Macros_1.scala +++ b/test/files/neg/macro-quasiquotes/Macros_1.scala @@ -9,7 +9,7 @@ trait Impls extends BlackboxMacro { } object Macros { - def m1(x: Int) = macro Impls.impl1 - def m2(x: Int) = macro Impls.impl2 - def m3(x: Int) = macro Impls.impl3 + def m1(x: Int): Unit = macro Impls.impl1 + def m2(x: Int): Unit = macro Impls.impl2 + def m3(x: Int): Unit = macro Impls.impl3 }
\ No newline at end of file diff --git a/test/files/neg/patmat-classtag-compound.check b/test/files/neg/patmat-classtag-compound.check new file mode 100644 index 0000000000..8a54c935bd --- /dev/null +++ b/test/files/neg/patmat-classtag-compound.check @@ -0,0 +1,6 @@ +patmat-classtag-compound.scala:12: warning: abstract type pattern A is unchecked since it is eliminated by erasure + case b: A with Bar => true + ^ +error: No warnings can be incurred under -Xfatal-warnings. +one warning found +one error found diff --git a/test/files/neg/patmat-classtag-compound.flags b/test/files/neg/patmat-classtag-compound.flags new file mode 100644 index 0000000000..144ddac9d3 --- /dev/null +++ b/test/files/neg/patmat-classtag-compound.flags @@ -0,0 +1 @@ +-unchecked -Xfatal-warnings diff --git a/test/files/neg/patmat-classtag-compound.scala b/test/files/neg/patmat-classtag-compound.scala new file mode 100644 index 0000000000..e2d0df0a02 --- /dev/null +++ b/test/files/neg/patmat-classtag-compound.scala @@ -0,0 +1,17 @@ +object Test extends App{ + trait Bar + trait Foo + // Failed to give an unchecked warning pre: https://github.com/scala/scala/pull/2848 + // + // Features interacting: + // - implicit class tags to enable type patterns on abstract types + // - type tests on compound types. + // + // We could try make these work together, but an unchecked warning is okay for now. + def x[A: reflect.ClassTag](a: Any): Boolean = a match{ + case b: A with Bar => true + case _ => false + } + println(x[Foo](new Bar{})) + println(x[String]("")) +} diff --git a/test/files/neg/quasiquotes-unliftable-not-found.check b/test/files/neg/quasiquotes-unliftable-not-found.check new file mode 100644 index 0000000000..5594aa1b15 --- /dev/null +++ b/test/files/neg/quasiquotes-unliftable-not-found.check @@ -0,0 +1,4 @@ +quasiquotes-unliftable-not-found.scala:4: error: Can't find reflect.runtime.universe.Unliftable[Test.C], consider providing it + val q"${c: C}" = q"()" + ^ +one error found diff --git a/test/files/neg/quasiquotes-unliftable-not-found.scala b/test/files/neg/quasiquotes-unliftable-not-found.scala new file mode 100644 index 0000000000..6a5efae43b --- /dev/null +++ b/test/files/neg/quasiquotes-unliftable-not-found.scala @@ -0,0 +1,5 @@ +object Test extends App { + import scala.reflect.runtime.universe._ + class C + val q"${c: C}" = q"()" +}
\ No newline at end of file diff --git a/test/files/neg/si7980.check b/test/files/neg/si7980.check new file mode 100644 index 0000000000..b085cabf1d --- /dev/null +++ b/test/files/neg/si7980.check @@ -0,0 +1,4 @@ +si7980.scala:7: error: Can't splice Nothing, bottom type values often indicate programmer mistake + println(q"class ${Name(X)} { }") + ^ +one error found diff --git a/test/files/neg/si7980.scala b/test/files/neg/si7980.scala new file mode 100644 index 0000000000..b21907de54 --- /dev/null +++ b/test/files/neg/si7980.scala @@ -0,0 +1,8 @@ +object Test extends App { + import scala.reflect.runtime.universe._ + def Name[T:TypeTag](name:String): T = implicitly[TypeTag[T]] match { + case t => newTypeName(name).asInstanceOf[T] + } + val X = "ASDF" + println(q"class ${Name(X)} { }") +} diff --git a/test/files/neg/t5753/Impls_Macros_1.scala b/test/files/neg/t5753/Impls_Macros_1.scala index f93d731d40..0e81e21c77 100644 --- a/test/files/neg/t5753/Impls_Macros_1.scala +++ b/test/files/neg/t5753/Impls_Macros_1.scala @@ -1,6 +1,6 @@ import scala.reflect.macros.{BlackboxContext => Ctx} trait Impls { -def impl(c: Ctx)(x: c.Expr[Any]) = x + def impl(c: Ctx)(x: c.Expr[Any]) = x } diff --git a/test/files/neg/t5753/Test_2.scala b/test/files/neg/t5753/Test_2.scala index f1cad67fed..150850a0eb 100644 --- a/test/files/neg/t5753/Test_2.scala +++ b/test/files/neg/t5753/Test_2.scala @@ -1,7 +1,7 @@ import scala.reflect.macros.{BlackboxContext => Ctx} object Macros extends Impls { - def foo(x: Any) = macro impl + def foo(x: Any): Any = macro impl } object Test extends App { diff --git a/test/files/neg/t5903a/Macros_1.scala b/test/files/neg/t5903a/Macros_1.scala index 7888b888e1..ce1b035260 100644 --- a/test/files/neg/t5903a/Macros_1.scala +++ b/test/files/neg/t5903a/Macros_1.scala @@ -7,7 +7,7 @@ case object SomeTree extends Tree object NewQuasiquotes { implicit class QuasiquoteInterpolation(c: StringContext) { object nq { - def unapply(t: Tree) = macro QuasiquoteMacros.unapplyImpl + def unapply(t: Tree): Any = macro QuasiquoteMacros.unapplyImpl } } } diff --git a/test/files/neg/t5903b/Macros_1.scala b/test/files/neg/t5903b/Macros_1.scala index 46f0eee0f1..dfe9d8d489 100644 --- a/test/files/neg/t5903b/Macros_1.scala +++ b/test/files/neg/t5903b/Macros_1.scala @@ -4,7 +4,7 @@ import language.experimental.macros object Interpolation { implicit class TestInterpolation(c: StringContext) { object t { - def unapply[T](x: T) = macro Macros.unapplyImpl[T] + def unapply[T](x: T): Any = macro Macros.unapplyImpl[T] } } } diff --git a/test/files/neg/t5903c/Macros_1.scala b/test/files/neg/t5903c/Macros_1.scala index 281a06e93c..d13c3c2ec2 100644 --- a/test/files/neg/t5903c/Macros_1.scala +++ b/test/files/neg/t5903c/Macros_1.scala @@ -4,7 +4,7 @@ import language.experimental.macros object Interpolation { implicit class TestInterpolation(c: StringContext) { object t { - def unapply[T](x: T) = macro Macros.unapplyImpl[T] + def unapply[T](x: T): Any = macro Macros.unapplyImpl[T] } } } diff --git a/test/files/neg/t5903d/Macros_1.scala b/test/files/neg/t5903d/Macros_1.scala index 5dd6220e1a..2d26e998a1 100644 --- a/test/files/neg/t5903d/Macros_1.scala +++ b/test/files/neg/t5903d/Macros_1.scala @@ -4,7 +4,7 @@ import language.experimental.macros object Interpolation { implicit class TestInterpolation(c: StringContext) { object t { - def unapply(x: Int) = macro Macros.unapplyImpl + def unapply(x: Int): Any = macro Macros.unapplyImpl } } } diff --git a/test/files/neg/t5903e/Macros_1.scala b/test/files/neg/t5903e/Macros_1.scala index 997e6fd073..5bdc25b832 100644 --- a/test/files/neg/t5903e/Macros_1.scala +++ b/test/files/neg/t5903e/Macros_1.scala @@ -4,7 +4,7 @@ import language.experimental.macros object Interpolation { implicit class TestInterpolation(c: StringContext) { object t { - def unapply(x: Int) = macro Macros.unapplyImpl + def unapply(x: Int): Any = macro Macros.unapplyImpl } } } diff --git a/test/files/neg/t6446-missing.check b/test/files/neg/t6446-missing.check index cd867289c3..029c8057c3 100755 --- a/test/files/neg/t6446-missing.check +++ b/test/files/neg/t6446-missing.check @@ -1,4 +1,4 @@ -Warning: class not found: t6446.Ploogin +Error: unable to load class: t6446.Ploogin phase name id description ---------- -- ----------- parser 1 parse source into ASTs, perform simple desugaring diff --git a/test/files/neg/t712.check b/test/files/neg/t712.check index 6819dc0ce9..831e943063 100644 --- a/test/files/neg/t712.check +++ b/test/files/neg/t712.check @@ -1,4 +1,5 @@ t712.scala:10: error: value self is not a member of B.this.ParentImpl + Note: implicit method coerce is not applicable here because it comes after the application point and it lacks an explicit result type implicit def coerce(p : ParentImpl) = p.self; ^ one error found diff --git a/test/files/neg/t7519-b.check b/test/files/neg/t7519-b.check index 08d819eeec..bc8500b2b8 100644 --- a/test/files/neg/t7519-b.check +++ b/test/files/neg/t7519-b.check @@ -1,4 +1,4 @@ -Use_2.scala:6: error: type mismatch; +Use_2.scala:8: error: type mismatch; found : String required: Q val x: Q = ex.Mac.mac("asdf") diff --git a/test/files/neg/t7519-b/Use_2.scala b/test/files/neg/t7519-b/Use_2.scala index 413e40e25e..0d63eeed5b 100644 --- a/test/files/neg/t7519-b/Use_2.scala +++ b/test/files/neg/t7519-b/Use_2.scala @@ -1,3 +1,5 @@ +import scala.language.implicitConversions + trait Q trait K diff --git a/test/files/neg/t8024.check b/test/files/neg/t8024.check new file mode 100644 index 0000000000..bd551aa591 --- /dev/null +++ b/test/files/neg/t8024.check @@ -0,0 +1,6 @@ +t8024.scala:13: error: reference to sqrt is ambiguous; +it is both defined in package object p and imported subsequently by +import java.lang.Math.sqrt + sqrt(0d) + ^ +one error found diff --git a/test/files/neg/t8024.scala b/test/files/neg/t8024.scala new file mode 100644 index 0000000000..b4c2c5ebb9 --- /dev/null +++ b/test/files/neg/t8024.scala @@ -0,0 +1,14 @@ +package p + +trait NRoot[A] + +object `package` { + final def sqrt(x: Double): Double = Math.sqrt(x) + final def sqrt[A](a: A)(implicit ev: NRoot[A]): A = ??? +} + +object FastComplex { + import java.lang.Math.sqrt + + sqrt(0d) +} diff --git a/test/files/neg/t8024b.check b/test/files/neg/t8024b.check new file mode 100644 index 0000000000..9cd89bca53 --- /dev/null +++ b/test/files/neg/t8024b.check @@ -0,0 +1,6 @@ +t8024b.scala:15: error: reference to sqrt is ambiguous; +it is both defined in object FastComplex and imported subsequently by +import java.lang.Math.sqrt + sqrt(0d) + ^ +one error found diff --git a/test/files/neg/t8024b.scala b/test/files/neg/t8024b.scala new file mode 100644 index 0000000000..cf3d496365 --- /dev/null +++ b/test/files/neg/t8024b.scala @@ -0,0 +1,17 @@ +package p + +trait NRoot[A] + +object FastComplex { + final def sqrt(x: Double): Double = Math.sqrt(x) + final def sqrt[A](a: A)(implicit ev: NRoot[A]): A = ??? + + object Inner { + import java.lang.Math.sqrt + + // wrong message: + // error: reference to sqrt is ambiguous; + // it is both defined in object FastComplex and imported subsequently by + sqrt(0d) + } +} diff --git a/test/files/pos/macro-implicit-invalidate-on-error.scala b/test/files/pos/macro-implicit-invalidate-on-error.scala index 22cd2d34b4..f9756d965f 100644 --- a/test/files/pos/macro-implicit-invalidate-on-error.scala +++ b/test/files/pos/macro-implicit-invalidate-on-error.scala @@ -1,23 +1,20 @@ -package scala.reflect -package api - import scala.language.experimental.macros import scala.reflect.macros.Context -trait Liftable[T] { - def apply(universe: api.Universe, value: T): universe.Tree +trait LegacyLiftable[T] { + def apply(universe: scala.reflect.api.Universe, value: T): universe.Tree } -object Liftable { - implicit def liftCaseClass[T <: Product]: Liftable[T] = macro liftCaseClassImpl[T] +object LegacyLiftable { + implicit def liftCaseClass[T <: Product]: LegacyLiftable[T] = macro liftCaseClassImpl[T] - def liftCaseClassImpl[T: c.WeakTypeTag](c: Context): c.Expr[Liftable[T]] = { + def liftCaseClassImpl[T: c.WeakTypeTag](c: Context): c.Expr[LegacyLiftable[T]] = { import c.universe._ val tpe = weakTypeOf[T] if (!tpe.typeSymbol.asClass.isCaseClass) c.abort(c.enclosingPosition, "denied") val p = List(q"Literal(Constant(1))") - c.Expr[Liftable[T]] { q""" - new scala.reflect.api.Liftable[$tpe] { + c.Expr[LegacyLiftable[T]] { q""" + new LegacyLiftable[$tpe] { def apply(universe: scala.reflect.api.Universe, value: $tpe): universe.Tree = { import universe._ Apply(Select(Ident(TermName("C")), TermName("apply")), List(..$p)) diff --git a/test/files/pos/t6780.scala b/test/files/pos/t6780.scala new file mode 100644 index 0000000000..4a358046c6 --- /dev/null +++ b/test/files/pos/t6780.scala @@ -0,0 +1,20 @@ +object O { + implicit def i: Int = 0 +} + +import O._ + +trait Foo { + implicit val v1: Any + implicit def d1: Any + val v2: Any + implicit val v3: Any +} + +trait Bar1 extends Foo { + implicit val v1 = {implicitly[Int]; ()} // failed due to cycle in Context#implicits being broken with Nil. + def d1 = {implicitly[Int]; ()} // okay + implicit val v2 = {implicitly[Int]; ()} // okay + implicit val v3: Any = {implicitly[Int]; ()} // okay + +} diff --git a/test/files/pos/t8001/Macros_1.scala b/test/files/pos/t8001/Macros_1.scala index 1f8dab51c1..fd26016d4b 100644 --- a/test/files/pos/t8001/Macros_1.scala +++ b/test/files/pos/t8001/Macros_1.scala @@ -2,7 +2,7 @@ import scala.language.experimental.macros import scala.reflect.macros.BlackboxContext object Macros { - def foo = macro impl + def foo: Unit = macro impl def impl(c: BlackboxContext) = { import c.universe._ q"()" diff --git a/test/files/pos/t8013.flags b/test/files/pos/t8013.flags new file mode 100644 index 0000000000..954eaba352 --- /dev/null +++ b/test/files/pos/t8013.flags @@ -0,0 +1 @@ +-Xfatal-warnings -Xlint diff --git a/test/files/pos/t8013/inpervolated_2.scala b/test/files/pos/t8013/inpervolated_2.scala new file mode 100644 index 0000000000..90e571b42c --- /dev/null +++ b/test/files/pos/t8013/inpervolated_2.scala @@ -0,0 +1,11 @@ +/* + * scalac: -Xfatal-warnings -Xlint + */ +package t8013 + +// unsuspecting user of perverse macro +trait User { + import Perverse.Impervolator + val foo = "bar" + Console println p"Hello, $foo" +} diff --git a/test/files/pos/t8013/inpervolator_1.scala b/test/files/pos/t8013/inpervolator_1.scala new file mode 100644 index 0000000000..fb71571afc --- /dev/null +++ b/test/files/pos/t8013/inpervolator_1.scala @@ -0,0 +1,33 @@ + +package t8013 + +// perverse macro to confuse Xlint + +import scala.language.experimental.macros +import scala.reflect.macros.{ BlackboxContext => Context } + +object Perverse { + + implicit class Impervolator(sc: StringContext) { + def p(args: Any*): String = macro pImpl + } + + // turn a nice interpolation into something that looks + // nothing like an interpolation or anything we might + // recognize, but which includes a "$id" in an apply. + def pImpl(c: Context)(args: c.Expr[Any]*): c.Expr[String] = { + import c.universe._ + val macroPos = c.macroApplication.pos + val text = macroPos.lineContent substring macroPos.column + val tt = Literal(Constant(text)) + val tree = q"t8013.Perverse.pervert($tt)" + c.Expr[String](tree) + } + + // identity doesn't seem very perverse in this context + //def pervert(text: String): String = text + def pervert(text: String): String = { + Console println s"Perverting [$text]" + text + } +} diff --git a/test/files/pos/t8054.scala b/test/files/pos/t8054.scala new file mode 100644 index 0000000000..a7bb44b1ed --- /dev/null +++ b/test/files/pos/t8054.scala @@ -0,0 +1,31 @@ +trait D { + trait Manifest { + class Entry + } + + val M: Manifest + + def m: M.Entry = ??? +} + +object D1 extends D { + object M extends Manifest +} + +object D2 extends D { + val M: Manifest = ??? +} + +object Hello { + + def main(args: Array[String]) { + // 2.10.3 - ok + // 2.11.0-M7 - type mismatch; found : Seq[DB1.MANIFEST.Entry] + // required: Seq[DB1.MANIFEST.Entry] + val t1: D1.M.Entry = D1.m + + // 2.10.3 - ok + // 2.11.0-M7 - ok + val t2: D2.M.Entry = D2.m + } +} diff --git a/test/files/pos/t8060.scala b/test/files/pos/t8060.scala new file mode 100644 index 0000000000..90e014d74b --- /dev/null +++ b/test/files/pos/t8060.scala @@ -0,0 +1,11 @@ +trait M[F[_]] + +trait P[A] { + type CC[X] = P[X] + def f(p: A => Boolean): M[CC] +} + +trait Other { + // was infinite loop trying to dealias `x$1.CC` + def g[A](p: A => Boolean): P[A] => M[P] = _ f p +} diff --git a/test/files/presentation/ide-t1001326.check b/test/files/presentation/ide-t1001326.check deleted file mode 100644 index 0ac15faed4..0000000000 --- a/test/files/presentation/ide-t1001326.check +++ /dev/null @@ -1,4 +0,0 @@ -Unique OK -Unattributed OK -NeverModify OK -AlwaysParseTree OK
\ No newline at end of file diff --git a/test/files/presentation/ide-t1001326/src/a/A.scala b/test/files/presentation/ide-t1001326/src/a/A.scala deleted file mode 100644 index c82ca02231..0000000000 --- a/test/files/presentation/ide-t1001326/src/a/A.scala +++ /dev/null @@ -1,5 +0,0 @@ -package a - -class A { - def foo(s: String) = s + s -}
\ No newline at end of file diff --git a/test/files/presentation/parse-invariants.check b/test/files/presentation/parse-invariants.check new file mode 100644 index 0000000000..32e9c846ab --- /dev/null +++ b/test/files/presentation/parse-invariants.check @@ -0,0 +1,5 @@ +NoNewSymbolsEntered OK +Unique OK +Unattributed OK +NeverModify OK +AlwaysParseTree OK diff --git a/test/files/presentation/ide-t1001326/Test.scala b/test/files/presentation/parse-invariants/Test.scala index ff63b9770a..128896ccaa 100644 --- a/test/files/presentation/ide-t1001326/Test.scala +++ b/test/files/presentation/parse-invariants/Test.scala @@ -6,16 +6,32 @@ object Test extends InteractiveTest { override def execute(): Unit = { val sf = sourceFiles.find(_.file.name == "A.scala").head - uniqueParseTree_t1001326(sf) - unattributedParseTree_t1001326(sf) - neverModifyParseTree_t1001326(sf) - shouldAlwaysReturnParseTree_t1001326(sf) + noNewSymbols(sf) + uniqueParseTree(sf) + unattributedParseTree(sf) + neverModifyParseTree(sf) + shouldAlwaysReturnParseTree(sf) + } + + /** + * Asking for a parseTree should not enter any new symbols. + */ + private def noNewSymbols(sf: SourceFile) { + def nextId() = compiler.NoSymbol.newTermSymbol(compiler.TermName("dummy"), compiler.NoPosition, compiler.NoFlags).id + val id = nextId() + val tree = compiler.parseTree(sf) + val id2 = nextId() + if (id2 == id + 1) { + reporter.println("NoNewSymbolsEntered OK") + } else { + reporter.println("NoNewSymbolsEntered FAILED") + } } /** * Asking twice for a parseTree on the same source should always return a new tree */ - private def uniqueParseTree_t1001326(sf: SourceFile) { + private def uniqueParseTree(sf: SourceFile) { val parseTree1 = compiler.parseTree(sf) val parseTree2 = compiler.parseTree(sf) if (parseTree1 != parseTree2) { @@ -28,7 +44,7 @@ object Test extends InteractiveTest { /** * A parseTree should never contain any symbols or types */ - private def unattributedParseTree_t1001326(sf: SourceFile) { + private def unattributedParseTree(sf: SourceFile) { if (noSymbolsOrTypes(compiler.parseTree(sf))) { reporter.println("Unattributed OK") } else { @@ -39,7 +55,7 @@ object Test extends InteractiveTest { /** * Once you have obtained a parseTree it should never change */ - private def neverModifyParseTree_t1001326(sf: SourceFile) { + private def neverModifyParseTree(sf: SourceFile) { val parsedTree = compiler.parseTree(sf) loadSourceAndWaitUntilTypechecked(sf) if (noSymbolsOrTypes(parsedTree)) { @@ -52,7 +68,7 @@ object Test extends InteractiveTest { /** * Should always return a parse tree */ - private def shouldAlwaysReturnParseTree_t1001326(sf: SourceFile) { + private def shouldAlwaysReturnParseTree(sf: SourceFile) { loadSourceAndWaitUntilTypechecked(sf) if (noSymbolsOrTypes(compiler.parseTree(sf))) { reporter.println("AlwaysParseTree OK") diff --git a/test/files/presentation/parse-invariants/src/a/A.scala b/test/files/presentation/parse-invariants/src/a/A.scala new file mode 100644 index 0000000000..1ae78cad05 --- /dev/null +++ b/test/files/presentation/parse-invariants/src/a/A.scala @@ -0,0 +1,138 @@ +package syntax + +object Terms { + object Literals { + 0 + 0l + 0f + 0d + 0xb33f + 'c' + "string" + """ + multi-line + string + """ + 'symbol + true + false + null + () + } + + object Patterns { + 0 match { case 0 => } + 1 match { case (0 | 1) => } + 2 match { case _: Int => } + 3 match { case _ => } + Some(0) match { case Some(0) => } + Some(0) match { case name @ Some(_) => } + Some(Some(0)) match { case nested @ Some(deeper @ Some(_)) => } + List(1, 2, 3) match { case unapplySeq @ List(1, 2, _*) => } + 0 match { case i if i > 0 => } + List(1) match { case _: List[t] => List.empty[t] } + } + + object New { + class Foo + trait Bar + new Foo + new Foo { selfie => } + new Foo with Bar + new { val early = 1 } with Bar + new { val name = "anon "} + } + + def tuple = (1, 'two, "three") + def lambda = (x: Int, y: Int) => x + y + def lambda2 = (_: Int) + (_: Int) + def blocks = { { {}; {} }; {} } + def ascription = (1: Int) + def select = Nil.size + def method1 = "s".replace("foo", "bar") + def method2 = "s" + "s" + def method3 = Nil.foreach { e => } + def method4 = 1 :: 2 :: 3 :: Nil + def if1 = if (true) true else false + def if2 = if (true) true + def `return`: Int = { return 0 } + def `throw` = throw new Exception + def `match` = 0 match { case 0 => case _ => } + def `try` = try 0 catch { case _ => } finally 0 + def `while` = while(true) 0 + def `do while` = do 0 while(true) + def `for` = for (i <- 1 to 10; if i % 2 == 0; j = i + 1) j + def `for yield` = for (a <- List(List(1)); b <- a; c = b * 2) yield b + def interpolation = s"$tuple and maybe also $blocks" + def assign = { var x = 1; x = 2 } + def assign2 = { object o { var x = 1 }; o.x = 2 } + def update = { val v = collection.mutable.Seq(1); v(0) = 2 } + def `this` = this +} + +object Types { + type Reference = scala.App + type Tuple = (Int, String, Double) + type Function = (Int, String) => Double + type Refined = Int { val meta: Any } + type Lambda = ({ type F[T] = List[T] })#F[_] + type Infix = Int Either String + type Application = List[Int] + type Existential = List[T] forSome { type T } + object O { type T = Int } + type Dependent = O.T + class O { type T = Int } + type Selection = O#T +} + +object Definitions { + private val x1 = 0 + private[this] val x2 = 0 + private[Definitions] val x3 = 0 + protected val x4 = 0 + protected[AcessManagement] val x5 = 0 + val x1 = 1 + val x2: Int = 1 + val x3, y3 = 1 + lazy val x4 = 1 + implicit val x5 = 1 + final val x6 = 1 + lazy final val x7 = 1 + val Some(x8) = Some(0) + var x9 = 1 + var x10, y10 = 1 + var x11: Int = 1 + + implicit def implicitView: Option[Int] = None + def implicitArg1(implicit i: Int) = i + 2 + def implicitArg2[T: Fooable] = implicitly[Fooable[T]] + def bound1[T <: Int](x: T): T = x + def bound2[T >: Any](x: T): T = x + def bound3[T <% Int](x: T): Int = x + def vararg(args: Int*) = args.toList + def sum(x: Int, y: Int) = x + y + def multipleArgLists(x: Int)(y: Int) = x + y + + type _0 = Int + type _1[T] = List[T] + type _2[A, B] = Either[A, B] + + class Val(value: Int) extends AnyVal + implicit class Impl(value: Int) { def foo = "foo" } + abstract class Abs + sealed class Sealed + class Child extends Sealed + case class Point(x: Int, y: Int) + + trait Fooable[T] + trait Barable with Fooable[Barable] + + object Foo + object Foo with Fooable[Foo] + case object Zero +} + +package Packages { + package object PackageObject + package Nested { package Deeper { } } +} diff --git a/test/files/presentation/scope-completion-2.check b/test/files/presentation/scope-completion-2.check index 3a1dbd7cff..d94f7a4b56 100644 --- a/test/files/presentation/scope-completion-2.check +++ b/test/files/presentation/scope-completion-2.check @@ -1,12 +1,11 @@ reload: Completions.scala -askScopeCompletion at Completions.scala(16,4) +askScopeCompletion at Completions.scala(15,2) ================================================================================ -[response] askScopeCompletion at (16,4) -retrieved 11 members +[response] askScopeCompletion at (15,2) +retrieved 10 members class Completion1 extends AnyRef def <init>(): test.Completion1 -def test: Unit object Completion1 private class Cc1 extends AnyRef private class Co1 extends AnyRef @@ -17,19 +16,18 @@ private[this] val vc1: Int private[this] val vo1: Int ================================================================================ -askScopeCompletion at Completions.scala(32,4) +askScopeCompletion at Completions.scala(29,2) ================================================================================ -[response] askScopeCompletion at (32,4) -retrieved 11 members -[inaccessible] private[this] val vc1: Int +[response] askScopeCompletion at (29,2) +retrieved 10 members class Completion1 extends AnyRef def <init>(): test.Completion1.type -def test: Unit object Completion1 private class Cc1 extends AnyRef private class Co1 extends AnyRef private def fc1: Int private def fo1: Int private[this] val c: test.Completion1 +private[this] val vc1: Int private[this] val vo1: Int ================================================================================ diff --git a/test/files/presentation/scope-completion-2/src/Completions.scala b/test/files/presentation/scope-completion-2/src/Completions.scala index 96d38f1b85..f8d7cd6ba8 100644 --- a/test/files/presentation/scope-completion-2/src/Completions.scala +++ b/test/files/presentation/scope-completion-2/src/Completions.scala @@ -9,12 +9,10 @@ class Completion1 { private val vc1 = 0 private def fc1 = 0 - private class Cc1 - - def test { - // needs to be done in a method, because of SI-7280 - /*_*/ + private class Cc1 { } + + /*_*/ } object Completion1 { @@ -25,11 +23,9 @@ object Completion1 { private val vo1 = 0 private def fo1 = 0 - private class Co1 - - def test { - // needs to be done in a method, because of SI-7280 - /*_*/ + private class Co1 { } + + /*_*/ } diff --git a/test/files/presentation/scope-completion-3.check b/test/files/presentation/scope-completion-3.check index cf73e89a3b..df3007ab4e 100644 --- a/test/files/presentation/scope-completion-3.check +++ b/test/files/presentation/scope-completion-3.check @@ -12,13 +12,9 @@ retrieved 49 members [inaccessible] private object Ot2 [inaccessible] private type tb2 = Completion1.this.tb2 [inaccessible] private type tt2 = Completion1.this.tt2 -[inaccessible] private[this] val vb1: Int [inaccessible] private[this] val vb2: Int -[inaccessible] private[this] val vt1: Int [inaccessible] private[this] val vt2: Int -[inaccessible] private[this] var rb1: Int [inaccessible] private[this] var rb2: Int -[inaccessible] private[this] var rt1: Int [inaccessible] private[this] var rt2: Int abstract class Base1 extends AnyRef abstract trait Trait1 extends AnyRef @@ -42,13 +38,17 @@ private class Cc2 extends AnyRef private def fc2: Int private object Oc2 private type tc2 = Completion1.this.tc2 +private[this] val vb1: Int private[this] val vb3: Int private[this] val vc1: Int private[this] val vc2: Int +private[this] val vt1: Int private[this] val vt3: Int +private[this] var rb1: Int private[this] var rb3: Int private[this] var rc1: Int private[this] var rc2: Int +private[this] var rt1: Int private[this] var rt3: Int type tb1 = Completion1.this.tb1 type tc1 = Completion1.this.tc1 @@ -67,13 +67,9 @@ retrieved 49 members [inaccessible] private object Ot2 [inaccessible] private type tb2 = test.Completion2.tb2 [inaccessible] private type tt2 = test.Completion2.tt2 -[inaccessible] private[this] val vb1: Int [inaccessible] private[this] val vb2: Int -[inaccessible] private[this] val vt1: Int [inaccessible] private[this] val vt2: Int -[inaccessible] private[this] var rb1: Int [inaccessible] private[this] var rb2: Int -[inaccessible] private[this] var rt1: Int [inaccessible] private[this] var rt2: Int abstract class Base1 extends AnyRef abstract trait Trait1 extends AnyRef @@ -97,13 +93,17 @@ private class Co2 extends AnyRef private def fo2: Int private object Oo2 private type to2 = test.Completion2.to2 +private[this] val vb1: Int private[this] val vb3: Int private[this] val vo1: Int private[this] val vo2: Int +private[this] val vt1: Int private[this] val vt3: Int +private[this] var rb1: Int private[this] var rb3: Int private[this] var ro1: Int private[this] var ro2: Int +private[this] var rt1: Int private[this] var rt3: Int type tb1 = test.Completion2.tb1 type to1 = test.Completion2.to1 diff --git a/test/files/presentation/scope-completion-import.check b/test/files/presentation/scope-completion-import.check index d518b0c37a..220ffc399b 100644 --- a/test/files/presentation/scope-completion-import.check +++ b/test/files/presentation/scope-completion-import.check @@ -1,9 +1,13 @@ reload: Completions.scala -askScopeCompletion at Completions.scala(15,4) -================================================================================ -[response] askScopeCompletion at (15,4) -retrieved 10 members +askScopeCompletion at Completions.scala(23,4) +================================================================================ +[response] askScopeCompletion at (23,4) +retrieved 18 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] val pVOOO: Int +[inaccessible] private[this] var pRCCC: Int +[inaccessible] private[this] var pROOO: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -13,13 +17,21 @@ def <init>(): test.Foo def fCCC: Int def fOOO: Int object O +private[this] val vCCC: Int +private[this] val vOOO: Int +private[this] var rCCC: Int +private[this] var rOOO: Int val o: test.O.type ================================================================================ -askScopeCompletion at Completions.scala(19,4) -================================================================================ -[response] askScopeCompletion at (19,4) -retrieved 9 members +askScopeCompletion at Completions.scala(27,4) +================================================================================ +[response] askScopeCompletion at (27,4) +retrieved 17 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] val pVOOO: Int +[inaccessible] private[this] var pRCCC: Int +[inaccessible] private[this] var pROOO: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -29,12 +41,18 @@ def <init>(): test.Foo def fCCC: Int def fOOO: Int object O +private[this] val vCCC: Int +private[this] val vOOO: Int +private[this] var rCCC: Int +private[this] var rOOO: Int ================================================================================ -askScopeCompletion at Completions.scala(24,4) +askScopeCompletion at Completions.scala(32,4) ================================================================================ -[response] askScopeCompletion at (24,4) -retrieved 9 members +[response] askScopeCompletion at (32,4) +retrieved 13 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] var pRCCC: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -43,12 +61,14 @@ class Foo_3 extends AnyRef def <init>(): test.Foo def fCCC: Int object O +private[this] val vCCC: Int +private[this] var rCCC: Int val c: test.C ================================================================================ -askScopeCompletion at Completions.scala(27,5) +askScopeCompletion at Completions.scala(35,5) ================================================================================ -[response] askScopeCompletion at (27,5) +[response] askScopeCompletion at (35,5) retrieved 8 members class C extends AnyRef class Foo extends AnyRef @@ -60,10 +80,12 @@ object O val c: test.C ================================================================================ -askScopeCompletion at Completions.scala(30,5) +askScopeCompletion at Completions.scala(38,5) ================================================================================ -[response] askScopeCompletion at (30,5) -retrieved 9 members +[response] askScopeCompletion at (38,5) +retrieved 13 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] var pRCCC: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -72,13 +94,19 @@ class Foo_3 extends AnyRef def <init>(): test.Foo def fCCC: Int object O +private[this] val vCCC: Int +private[this] var rCCC: Int val c: test.C ================================================================================ -askScopeCompletion at Completions.scala(32,5) -================================================================================ -[response] askScopeCompletion at (32,5) -retrieved 10 members +askScopeCompletion at Completions.scala(40,5) +================================================================================ +[response] askScopeCompletion at (40,5) +retrieved 18 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] val pVOOO: Int +[inaccessible] private[this] var pRCCC: Int +[inaccessible] private[this] var pROOO: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -88,13 +116,21 @@ def <init>(): test.Foo def fCCC: Int def fOOO: Int object O +private[this] val vCCC: Int +private[this] val vOOO: Int +private[this] var rCCC: Int +private[this] var rOOO: Int val c: test.C ================================================================================ -askScopeCompletion at Completions.scala(41,4) -================================================================================ -[response] askScopeCompletion at (41,4) -retrieved 10 members +askScopeCompletion at Completions.scala(49,4) +================================================================================ +[response] askScopeCompletion at (49,4) +retrieved 18 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] val pVOOO: Int +[inaccessible] private[this] var pRCCC: Int +[inaccessible] private[this] var pROOO: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -105,12 +141,20 @@ def bar: Unit def fCCC: Int def fOOO: Int object O +private[this] val vCCC: Int +private[this] val vOOO: Int +private[this] var rCCC: Int +private[this] var rOOO: Int ================================================================================ -askScopeCompletion at Completions.scala(51,4) -================================================================================ -[response] askScopeCompletion at (51,4) -retrieved 11 members +askScopeCompletion at Completions.scala(59,4) +================================================================================ +[response] askScopeCompletion at (59,4) +retrieved 19 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] val pVOOO: Int +[inaccessible] private[this] var pRCCC: Int +[inaccessible] private[this] var pROOO: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -122,12 +166,18 @@ def fCCC: Int def fOOO: Int object O private[this] val o: test.O.type +private[this] val vCCC: Int +private[this] val vOOO: Int +private[this] var rCCC: Int +private[this] var rOOO: Int ================================================================================ -askScopeCompletion at Completions.scala(61,4) +askScopeCompletion at Completions.scala(69,4) ================================================================================ -[response] askScopeCompletion at (61,4) -retrieved 10 members +[response] askScopeCompletion at (69,4) +retrieved 14 members +[inaccessible] private[this] val pVCCC: Int +[inaccessible] private[this] var pRCCC: Int class C extends AnyRef class Foo extends AnyRef class Foo_1 extends AnyRef @@ -138,4 +188,6 @@ def bar: Unit def fCCC: Int object O private[this] val c: test.C +private[this] val vCCC: Int +private[this] var rCCC: Int ================================================================================ diff --git a/test/files/presentation/scope-completion-import/src/Completions.scala b/test/files/presentation/scope-completion-import/src/Completions.scala index 6e08321283..d30aa0b4e3 100644 --- a/test/files/presentation/scope-completion-import/src/Completions.scala +++ b/test/files/presentation/scope-completion-import/src/Completions.scala @@ -1,10 +1,18 @@ package test class C { + val vCCC : Int = 0 + var rCCC : Int = 0 + private val pVCCC : Int = 0 + private var pRCCC : Int = 0 def fCCC : Int = 0 } object O extends C { + val vOOO : Int = 0 + var rOOO : Int = 0 + private val pVOOO : Int = 0 + private var pROOO : Int = 0 def fOOO : Int = 0 } diff --git a/test/files/run/iq.check b/test/files/run/iq.check index 81114ea181..311bf83ed4 100644 --- a/test/files/run/iq.check +++ b/test/files/run/iq.check @@ -1,4 +1,8 @@ Empty +q2: Queue(42, 0) +qa: Queue(42, 0) +qb: Queue(42, 0) +qc: Queue(42, 0) Head: 42 q5: Queue(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) q5[5]: 5 diff --git a/test/files/run/iq.scala b/test/files/run/iq.scala index 31859cf867..1eb1d40e37 100644 --- a/test/files/run/iq.scala +++ b/test/files/run/iq.scala @@ -16,10 +16,21 @@ object iq { Console.println("Empty") } - /* Test infix enqueing. */ - //val q2 = q + 42 + 0 // deprecated + /* Test enqueing. */ val q2 = q.enqueue(42).enqueue(0) + val qa = q :+ 42 :+ 0 + assert(q2 == qa) + + val qb = 42 +: 0 +: q + assert(q2 == qb) + val qc = 42 +: q :+ 0 + assert(q2 == qc) + Console.println("q2: " + q2) + Console.println("qa: " + qa) + Console.println("qb: " + qb) + Console.println("qc: " + qc) + /* Test is empty and dequeue. * Expected: Head: 42 */ @@ -37,7 +48,7 @@ object iq { /* Test sequence enqueing. */ val q5: Queue[Any] = q4.enqueue(List(1,2,3,4,5,6,7,8,9)) /* Test toString. - * Expected: Head: q5: Queue(0,1,2,3,4,5,6,7,8,9) + * Expected: q5: Queue(0,1,2,3,4,5,6,7,8,9) */ Console.println("q5: " + q5) /* Test apply diff --git a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala index 0a9f9a0ced..8506239952 100644 --- a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala +++ b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala @@ -4,7 +4,7 @@ import scala.reflect.macros.{BlackboxContext, WhiteboxContext} object Impls { def foo(c: BlackboxContext)(x: c.Expr[Int]) = x - def refToFoo(dummy: Int) = macro refToFoo_impl + def refToFoo(dummy: Int): Int = macro refToFoo_impl def refToFoo_impl(c: WhiteboxContext)(dummy: c.Expr[Int]) = { import c.universe._ val body = Select(Ident(TermName("Impls")), TermName("foo")) diff --git a/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala index cfcb59c17b..486e1de090 100644 --- a/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala +++ b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala @@ -1,7 +1,7 @@ import scala.language.experimental.macros object Macros { - def foo(x: Int) = macro Impls.refToFoo(42) + def foo(x: Int): Int = macro Impls.refToFoo(42) } object Test extends App { diff --git a/test/files/run/macro-bundle-repl.check b/test/files/run/macro-bundle-repl.check index 795debded7..8487042d66 100644 --- a/test/files/run/macro-bundle-repl.check +++ b/test/files/run/macro-bundle-repl.check @@ -7,7 +7,7 @@ import scala.language.experimental.macros scala> import scala.reflect.macros.BlackboxMacro import scala.reflect.macros.BlackboxMacro -scala> trait Bar extends BlackboxMacro { def impl = { import c.universe._; c.Expr[Unit](q"()") } };def bar = macro Bar.impl +scala> trait Bar extends BlackboxMacro { def impl = { import c.universe._; c.Expr[Unit](q"()") } };def bar: Unit = macro Bar.impl defined trait Bar defined term macro bar: Unit @@ -16,7 +16,7 @@ scala> bar scala> trait Foo extends BlackboxMacro { def impl = { import c.universe._; c.Expr[Unit](q"()") } } defined trait Foo -scala> def foo = macro Foo.impl +scala> def foo: Unit = macro Foo.impl defined term macro foo: Unit scala> foo diff --git a/test/files/run/macro-bundle-repl.scala b/test/files/run/macro-bundle-repl.scala index 50811cdb65..db64f05943 100644 --- a/test/files/run/macro-bundle-repl.scala +++ b/test/files/run/macro-bundle-repl.scala @@ -4,10 +4,10 @@ object Test extends ReplTest { def code = """ import scala.language.experimental.macros import scala.reflect.macros.BlackboxMacro -trait Bar extends BlackboxMacro { def impl = { import c.universe._; c.Expr[Unit](q"()") } };def bar = macro Bar.impl +trait Bar extends BlackboxMacro { def impl = { import c.universe._; c.Expr[Unit](q"()") } };def bar: Unit = macro Bar.impl bar trait Foo extends BlackboxMacro { def impl = { import c.universe._; c.Expr[Unit](q"()") } } -def foo = macro Foo.impl +def foo: Unit = macro Foo.impl foo """ } diff --git a/test/files/run/macro-def-infer-return-type.check b/test/files/run/macro-def-infer-return-type.check deleted file mode 100644 index fbd164f139..0000000000 --- a/test/files/run/macro-def-infer-return-type.check +++ /dev/null @@ -1,8 +0,0 @@ -42 -reflective compilation has failed: - -exception during macro expansion: -java.lang.Error: an implementation is missing - at Impls2$.foo(Impls_1.scala:9) - -42 diff --git a/test/files/run/macro-def-infer-return-type.flags b/test/files/run/macro-def-infer-return-type.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-infer-return-type.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type/Impls_1.scala b/test/files/run/macro-def-infer-return-type/Impls_1.scala deleted file mode 100644 index c670b1e57e..0000000000 --- a/test/files/run/macro-def-infer-return-type/Impls_1.scala +++ /dev/null @@ -1,14 +0,0 @@ -import scala.reflect.macros.BlackboxContext - -object Impls1 { - def foo(c: BlackboxContext)(x: c.Expr[Int]) = x -} - -object Impls2 { - def foo[T](c: BlackboxContext)(x: c.Expr[T]) = - throw new Error("an implementation is missing") -} - -object Impls3 { - def foo[T](c: BlackboxContext)(x: c.Expr[T]): c.Expr[T] = x -} diff --git a/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala deleted file mode 100644 index f579586b7f..0000000000 --- a/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala +++ /dev/null @@ -1,24 +0,0 @@ -object Macros1 { - def foo(x: Int) = macro Impls1.foo -} - -object Macros2 { - def foo[T](x: T) = macro Impls2.foo[T] -} - -object Macros3 { - def foo[T](x: T) = macro Impls3.foo[T] -} - -object Test extends App { - println(Macros1.foo(42)) - - import scala.reflect.runtime.universe._ - import scala.reflect.runtime.{currentMirror => cm} - import scala.tools.reflect.ToolBox - val tree = Apply(Select(Ident(TermName("Macros2")), TermName("foo")), List(Literal(Constant(42)))) - try cm.mkToolBox().eval(tree) - catch { case ex: Throwable => println(ex.getMessage) } - - println(Macros3.foo(42)) -} diff --git a/test/files/run/macro-def-path-dependent/Test_1.scala b/test/files/run/macro-def-path-dependent/Test_1.scala index f9aa13c334..bba97fcae1 100644 --- a/test/files/run/macro-def-path-dependent/Test_1.scala +++ b/test/files/run/macro-def-path-dependent/Test_1.scala @@ -1,23 +1,25 @@ -package test1 - -import scala.reflect.macros.{BlackboxContext => Ctx} - -trait Exprs { - self: Universe => - - class Expr[T] -} - -trait Reifiers { - self: Universe => - - type Expr[T] - - def reify[T](expr: T) = macro Impls.reify[T] -} - -trait Universe extends Exprs with Reifiers - -object Impls { - def reify[T](cc: Ctx{ type PrefixType = Reifiers })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? -} +// NOTE: blocked by SI-8049 + +// package test1 +// +// import scala.reflect.macros.{BlackboxContext => Ctx} +// +// trait Exprs { +// self: Universe => +// +// class Expr[T] +// } +// +// trait Reifiers { +// self: Universe => +// +// type Expr[T] +// +// def reify[T](expr: T): Expr[T] = macro Impls.reify[T] +// } +// +// trait Universe extends Exprs with Reifiers +// +// object Impls { +// def reify[T](cc: Ctx{ type PrefixType = Reifiers })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ??? +// } diff --git a/test/files/run/macro-def-path-dependent/Test_2.scala b/test/files/run/macro-def-path-dependent/Test_2.scala index cdedaf2732..c884ab9d0b 100644 --- a/test/files/run/macro-def-path-dependent/Test_2.scala +++ b/test/files/run/macro-def-path-dependent/Test_2.scala @@ -14,7 +14,7 @@ trait Reifiers { } trait Universe extends Exprs with Reifiers { - def reify[T](expr: T) = macro Impls.reify[T] + def reify[T](expr: T): Expr[T] = macro Impls.reify[T] } object Impls { diff --git a/test/files/run/macro-def-path-dependent/Test_4.scala b/test/files/run/macro-def-path-dependent/Test_4.scala index e8a8cf3909..6562802013 100644 --- a/test/files/run/macro-def-path-dependent/Test_4.scala +++ b/test/files/run/macro-def-path-dependent/Test_4.scala @@ -5,7 +5,7 @@ import scala.reflect.macros.BlackboxContext import scala.reflect.api.Universe object Test { - def materializeTypeTag[T](u: Universe)(e: T) = macro materializeTypeTag_impl[T] + def materializeTypeTag[T](u: Universe)(e: T): u.TypeTag[T] = macro materializeTypeTag_impl[T] def materializeTypeTag_impl[T: c.WeakTypeTag](c: BlackboxContext)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ??? }
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent/Test_6.scala b/test/files/run/macro-def-path-dependent/Test_6.scala index c8ddffc143..011e726b3f 100644 --- a/test/files/run/macro-def-path-dependent/Test_6.scala +++ b/test/files/run/macro-def-path-dependent/Test_6.scala @@ -5,5 +5,5 @@ import scala.reflect.macros.BlackboxContext import scala.reflect.api.Universe object Macros { - def materializeTypeTag[T](u: Universe)(e: T) = macro Impls.materializeTypeTag_impl[T] + def materializeTypeTag[T](u: Universe)(e: T): u.TypeTag[T] = macro Impls.materializeTypeTag_impl[T] }
\ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala index ffb04dc80b..fec914632f 100644 --- a/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala +++ b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Test extends App { implicit val x = 42 - def foo(implicit x: Int) = macro Impls.foo + def foo(implicit x: Int): Unit = macro Impls.foo foo }
\ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala index b91b1016c9..2f21785bae 100644 --- a/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala +++ b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Test extends App { - implicit def foo = macro Impls.foo + implicit def foo: Int = macro Impls.foo def bar(implicit x: Int) = println(x) bar }
\ No newline at end of file diff --git a/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala index fa4504b0ea..54b959983b 100644 --- a/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala +++ b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala @@ -1,4 +1,4 @@ object Test extends App { - def foo(x: Int)(y: Int) = macro Impls.foo + def foo(x: Int)(y: Int): Unit = macro Impls.foo foo(40)(2) }
\ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala index 2d5cf53c3c..edd9051754 100644 --- a/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala +++ b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala @@ -1,8 +1,8 @@ object Macros { - def foo1[T] = macro Impls.fooNullary[T] - def foo2[T]() = macro Impls.fooEmpty[T] - def bar1[T](x: Int) = macro Impls.barNullary[T] - def bar2[T](x: Int)() = macro Impls.barEmpty[T] + def foo1[T]: Unit = macro Impls.fooNullary[T] + def foo2[T](): Unit = macro Impls.fooEmpty[T] + def bar1[T](x: Int): Unit = macro Impls.barNullary[T] + def bar2[T](x: Int)(): Unit = macro Impls.barEmpty[T] } object Test extends App { diff --git a/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala index 1f6d717956..51915dfb27 100644 --- a/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala +++ b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala @@ -1,8 +1,8 @@ object Macros { - def foo1 = macro Impls.fooNullary - def foo2() = macro Impls.fooEmpty - def bar1(x: Int) = macro Impls.barNullary - def bar2(x: Int)() = macro Impls.barEmpty + def foo1: Unit = macro Impls.fooNullary + def foo2(): Unit = macro Impls.fooEmpty + def bar1(x: Int): Unit = macro Impls.barNullary + def bar2(x: Int)(): Unit = macro Impls.barEmpty } object Test extends App { diff --git a/test/files/run/macro-expand-overload/Macros_Test_2.scala b/test/files/run/macro-expand-overload/Macros_Test_2.scala index 7f61f85184..87cff2ecbd 100644 --- a/test/files/run/macro-expand-overload/Macros_Test_2.scala +++ b/test/files/run/macro-expand-overload/Macros_Test_2.scala @@ -1,13 +1,13 @@ object Macros { - def foo(x: String) = macro Impls.fooObjectString - def foo(x: Int) = macro Impls.fooObjectInt - def foo(x: Boolean) = println("fooObjectBoolean") + def foo(x: String): Unit = macro Impls.fooObjectString + def foo(x: Int): Unit = macro Impls.fooObjectInt + def foo(x: Boolean): Unit = println("fooObjectBoolean") } class Macros { - def foo(x: String) = macro Impls.fooClassString - def foo(x: Int) = macro Impls.fooClassInt - def foo(x: Boolean) = println("fooClassBoolean") + def foo(x: String): Unit = macro Impls.fooClassString + def foo(x: Int): Unit = macro Impls.fooClassInt + def foo(x: Boolean): Unit = println("fooClassBoolean") } object Test extends App { diff --git a/test/files/run/macro-expand-override/Macros_Test_2.scala b/test/files/run/macro-expand-override/Macros_Test_2.scala index f162773c95..160831c54e 100644 --- a/test/files/run/macro-expand-override/Macros_Test_2.scala +++ b/test/files/run/macro-expand-override/Macros_Test_2.scala @@ -1,17 +1,17 @@ class B { - def foo(x: String) = macro Impls.fooBString - def foo(x: Int) = macro Impls.fooBInt - def foo(x: Boolean) = println("fooBBoolean") + def foo(x: String): Unit = macro Impls.fooBString + def foo(x: Int): Unit = macro Impls.fooBInt + def foo(x: Boolean): Unit = println("fooBBoolean") } class D extends B { - //override def foo(x: String) = println("fooDString") => method cannot override a macro - override def foo(x: Int) = macro Impls.fooDInt + //override def foo(x: String): Unit = println("fooDString") => method cannot override a macro + override def foo(x: Int): Unit = macro Impls.fooDInt } class Z extends D { - override def foo(x: String) = macro Impls.fooZString - override def foo(x: Boolean) = println("fooZBoolean") + override def foo(x: String): Unit = macro Impls.fooZString + override def foo(x: Boolean): Unit = println("fooZBoolean") } object Test extends App { diff --git a/test/files/run/macro-expand-recursive/Macros_Test_2.scala b/test/files/run/macro-expand-recursive/Macros_Test_2.scala index 6ff691bdb1..5332fdacee 100644 --- a/test/files/run/macro-expand-recursive/Macros_Test_2.scala +++ b/test/files/run/macro-expand-recursive/Macros_Test_2.scala @@ -1,6 +1,6 @@ object Macros { - def foo = macro Impls.foo - def fooFoo = macro Impls.fooFoo + def foo: Unit = macro Impls.foo + def fooFoo: Unit = macro Impls.fooFoo } object Test extends App { diff --git a/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala index 37a4bcb2b9..6cb2b53465 100644 --- a/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala +++ b/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala @@ -1,9 +1,9 @@ object Macros1 { - def foo[U <: String] = macro Impls1.foo[U] + def foo[U <: String]: Unit = macro Impls1.foo[U] } object Macros2 { - def foo[T <: D] = macro Impls2.foo[T] + def foo[T <: D]: Unit = macro Impls2.foo[T] } object Test extends App { diff --git a/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala index e72c27881a..2cf7b19d2a 100644 --- a/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala +++ b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala @@ -1,4 +1,4 @@ object Test extends App { - def foo[U] = macro Impls.foo[U] + def foo[U]: Unit = macro Impls.foo[U] foo[Int] }
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala index f8c573f509..1192931931 100644 --- a/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala +++ b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Test extends App { - def foo[U](x: U) = macro Impls.foo[U] + def foo[U](x: U): Unit = macro Impls.foo[U] foo(42) foo("42") }
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala index 2b1730d36e..c8f68b4aff 100644 --- a/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala +++ b/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala @@ -1,19 +1,19 @@ object Macros1 { class C[T] { - def foo[U](x: U) = macro Impls1.foo[U] + def foo[U](x: U): Unit = macro Impls1.foo[U] } } object Macros2 { class C[T] { - def foo[U](x: U) = macro Impls2.foo[T, U] + def foo[U](x: U): Unit = macro Impls2.foo[T, U] } } object Macros3 { class D[T] { class C[U] { - def foo[V] = macro Impls345.foo[T, U, V] + def foo[V]: Unit = macro Impls345.foo[T, U, V] } } } @@ -23,7 +23,7 @@ object Macros3 { object Macros5 { class D[T] { class C[U] { - def foo[V] = macro Impls345.foo[T, U, V] + def foo[V]: Unit = macro Impls345.foo[T, U, V] foo[Boolean] } } diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala index b844012d53..6d79b13419 100644 --- a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo(xs: Int*) = macro Impls.foo + def foo(xs: Int*): Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala index f127ebcde7..13d7cd5d5d 100644 --- a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo(xs: Int*) = macro Impls.foo + def foo(xs: Int*): Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala index f127ebcde7..13d7cd5d5d 100644 --- a/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo(xs: Int*) = macro Impls.foo + def foo(xs: Int*): Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala index 2311ca0b95..9ab1be9e23 100644 --- a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo(xs: Int*) = macro Impls.foo + def foo(xs: Int*): Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala index 2311ca0b95..9ab1be9e23 100644 --- a/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo(xs: Int*) = macro Impls.foo + def foo(xs: Int*): Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala b/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala index 218c7aec7f..4901e24481 100644 --- a/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala +++ b/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo = macro Impls.foo[String] + def foo: Unit = macro Impls.foo[String] } object Test extends App { diff --git a/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala b/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala index e72c27881a..2cf7b19d2a 100644 --- a/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala +++ b/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala @@ -1,4 +1,4 @@ object Test extends App { - def foo[U] = macro Impls.foo[U] + def foo[U]: Unit = macro Impls.foo[U] foo[Int] }
\ No newline at end of file diff --git a/test/files/run/macro-quasiquotes/Macros_1.scala b/test/files/run/macro-quasiquotes/Macros_1.scala index c42baafdf4..81775d98e8 100644 --- a/test/files/run/macro-quasiquotes/Macros_1.scala +++ b/test/files/run/macro-quasiquotes/Macros_1.scala @@ -9,7 +9,7 @@ trait Impls extends BlackboxMacro { } object Macros { - def m1 = macro Impls.impl1 - def m2 = macro Impls.impl2 - def m3 = macro Impls.impl3 + def m1: Unit = macro Impls.impl1 + def m2: Unit = macro Impls.impl2 + def m3: Int = macro Impls.impl3 }
\ No newline at end of file diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check index f77196b2db..920a139664 100644 --- a/test/files/run/macro-reflective-mamd-normal-mi.check +++ b/test/files/run/macro-reflective-mamd-normal-mi.check @@ -1,2 +1 @@ -warning: there were 1 deprecation warning(s); re-run with -deprecation for details 43 diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala index 13cd953bde..ba12fb05e6 100644 --- a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala +++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala @@ -10,9 +10,9 @@ object Test extends App { val macrobody = Select(Ident(TermName("Impls")), TermName("foo")) val macroparam = ValDef(NoMods, TermName("x"), TypeTree(definitions.IntClass.toType), EmptyTree) - val macrodef = DefDef(Modifiers(MACRO), TermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody) + val macrodef = DefDef(Modifiers(MACRO), TermName("foo"), Nil, List(List(macroparam)), Ident(TypeName("Int")), macrobody) val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))) - val module = ModuleDef(NoMods, TermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef))) + val module = ModuleDef(NoMods, TermName("Macros"), Template(Nil, noSelfType, List(modulector, macrodef))) val macroapp = Apply(Select(Ident(TermName("Macros")), TermName("foo")), List(Literal(Constant(42)))) val tree = Block(List(macrodef, module), macroapp) val toolbox = cm.mkToolBox(options = "-language:experimental.macros") diff --git a/test/files/run/macro-reify-ref-to-packageless/Test_2.scala b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala index 9d475f756d..c167b160be 100644 --- a/test/files/run/macro-reify-ref-to-packageless/Test_2.scala +++ b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala @@ -1,4 +1,4 @@ object Test extends App { - def foo = macro Impls.foo + def foo: Int = macro Impls.foo println(foo) }
\ No newline at end of file diff --git a/test/files/run/macro-repl-dontexpand.check b/test/files/run/macro-repl-dontexpand.check index 3ba877b59d..9f538c04b6 100644 --- a/test/files/run/macro-repl-dontexpand.check +++ b/test/files/run/macro-repl-dontexpand.check @@ -5,12 +5,12 @@ scala> def bar1(c: scala.reflect.macros.BlackboxContext) = ??? bar1: (c: scala.reflect.macros.BlackboxContext)Nothing scala> def foo1 = macro bar1 -defined term macro foo1: Any +defined term macro foo1: Nothing scala> def bar2(c: scala.reflect.macros.WhiteboxContext) = ??? bar2: (c: scala.reflect.macros.WhiteboxContext)Nothing scala> def foo2 = macro bar2 -defined term macro foo2: Any +defined term macro foo2: Nothing scala> diff --git a/test/files/run/macro-subpatterns.check b/test/files/run/macro-subpatterns.check new file mode 100644 index 0000000000..b34d4bf4a1 --- /dev/null +++ b/test/files/run/macro-subpatterns.check @@ -0,0 +1,3 @@ +List((a @ Extractor((b @ Extractor((c @ _)))))) +List((b @ Extractor((c @ _)))) +List((c @ _)) diff --git a/test/files/run/macro-subpatterns/Macro_1.scala b/test/files/run/macro-subpatterns/Macro_1.scala new file mode 100644 index 0000000000..d8e86e27c6 --- /dev/null +++ b/test/files/run/macro-subpatterns/Macro_1.scala @@ -0,0 +1,18 @@ +import scala.reflect.macros.WhiteboxContext +import language.experimental.macros + +object Extractor { + def unapply(x: Any): Any = macro unapplyImpl + def unapplyImpl(c: WhiteboxContext)(x: c.Tree) = { + val st = c.universe.asInstanceOf[reflect.internal.SymbolTable] + import st._ + val subpatterns = x.attachments.get[SubpatternsAttachment].get.patterns + q""" + new { + def isEmpty = false + def get = ${subpatterns.toString} + def unapply(x: Any) = this + }.unapply(${x.asInstanceOf[st.Tree]}) + """.asInstanceOf[c.Tree] + } +} diff --git a/test/files/run/macro-subpatterns/Test_2.scala b/test/files/run/macro-subpatterns/Test_2.scala new file mode 100644 index 0000000000..dc6e668877 --- /dev/null +++ b/test/files/run/macro-subpatterns/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + 42 match { + case Extractor(a @ Extractor(b @ Extractor(c))) => println(a); println(b); println(c) + } +} diff --git a/test/files/run/macro-system-properties.check b/test/files/run/macro-system-properties.check index ea4c5a664a..ceed1079b2 100644 --- a/test/files/run/macro-system-properties.check +++ b/test/files/run/macro-system-properties.check @@ -9,7 +9,7 @@ scala> object GrabContext { def lastContext = Option(System.getProperties.get("lastContext").asInstanceOf[reflect.macros.runtime.Context]) // System.properties lets you stash true globals (unlike statics which are classloader scoped) def impl(c: BlackboxContext)() = { import c.universe._; System.getProperties.put("lastContext", c); c.Expr[Unit](q"()") } - def grab() = macro impl + def grab(): Unit = macro impl } defined object GrabContext diff --git a/test/files/run/macro-system-properties.scala b/test/files/run/macro-system-properties.scala index 73a3ef5910..3325c1747a 100644 --- a/test/files/run/macro-system-properties.scala +++ b/test/files/run/macro-system-properties.scala @@ -8,7 +8,7 @@ object Test extends ReplTest { def lastContext = Option(System.getProperties.get("lastContext").asInstanceOf[reflect.macros.runtime.Context]) // System.properties lets you stash true globals (unlike statics which are classloader scoped) def impl(c: BlackboxContext)() = { import c.universe._; System.getProperties.put("lastContext", c); c.Expr[Unit](q"()") } - def grab() = macro impl + def grab(): Unit = macro impl } object Test { class C(implicit a: Any) { GrabContext.grab } } object Test { class C(implicit a: Any) { GrabContext.grab } } diff --git a/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala index 88cd29ae4f..5039dffd5f 100644 --- a/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala @@ -1,6 +1,6 @@ import scala.language.reflectiveCalls object Test extends App { - val macros = new { def foo = macro Impls.foo } + val macros = new { def foo: Unit = macro Impls.foo } macros.foo } diff --git a/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala index 69088e24bc..80bfc44bee 100644 --- a/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala @@ -1,6 +1,6 @@ object Test extends App { { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo foo } }
\ No newline at end of file diff --git a/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala index 871857a97f..d6b1f9fab1 100644 --- a/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala @@ -1,6 +1,6 @@ class Macros { class Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } } diff --git a/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala index 994f9fe935..957f666bb0 100644 --- a/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala @@ -1,6 +1,6 @@ class Macros { object Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } } diff --git a/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala index 1b9d13e775..5898d94dc1 100644 --- a/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala @@ -1,5 +1,5 @@ class Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala index 356029e63e..16bd95b1e6 100644 --- a/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Test extends App { - def foo(bar: String = { def foo = macro Impls.foo; foo }) = println(bar) + def foo(bar: String = { def foo: String = macro Impls.foo; foo }) = println(bar) foo() foo("it works") diff --git a/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala index ed5c8b7c43..523989df13 100644 --- a/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala @@ -1,6 +1,6 @@ object Test extends App { def bar() = { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo foo } diff --git a/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala index 204deed61c..fe9dbef255 100644 --- a/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala @@ -1,6 +1,6 @@ object Macros { class Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } } diff --git a/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala index e261a50f3d..4ba7551818 100644 --- a/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala @@ -1,6 +1,6 @@ object Macros { object Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } } diff --git a/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala index a5a4862ba0..9ebf5d7dba 100644 --- a/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala @@ -1,5 +1,5 @@ object Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala index 54a5962e80..1f378b8bfd 100644 --- a/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala @@ -1,5 +1,5 @@ package object Macros { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } object Test extends App { diff --git a/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala index ff9a66d58a..b38616b71a 100644 --- a/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala @@ -1,9 +1,8 @@ - import scala.language.reflectiveCalls class Base object Test extends App { - val macros = new Base { def foo = macro Impls.foo } + val macros = new Base { def foo: Unit = macro Impls.foo } macros.foo } diff --git a/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala index f75906b636..09c60df351 100644 --- a/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala @@ -1,5 +1,5 @@ trait Base { - def foo = macro Impls.foo + def foo: Unit = macro Impls.foo } object Macros extends Base diff --git a/test/files/run/macro-vampire-false-warning/Macros_1.scala b/test/files/run/macro-vampire-false-warning/Macros_1.scala index 5907461c84..bf75e924e8 100644 --- a/test/files/run/macro-vampire-false-warning/Macros_1.scala +++ b/test/files/run/macro-vampire-false-warning/Macros_1.scala @@ -22,7 +22,7 @@ object Macros { // val fields = kvps map { case (k, v) => q"@body($v) def ${TermName(k)} = macro Macros.selFieldImpl" } val fields = kvps map { case (k, v) => DefDef( Modifiers(MACRO, tpnme.EMPTY, List(Apply(Select(New(Ident(TypeName("body"))), nme.CONSTRUCTOR), List(v)))), - TermName(k), Nil, Nil, TypeTree(), Select(Ident(TermName("Macros")), TermName("selFieldImpl"))) } + TermName(k), Nil, Nil, Ident(TypeName("Any")), Select(Ident(TermName("Macros")), TermName("selFieldImpl"))) } // q"import scala.language.experimental.macros; class Workaround { ..$fields }; new Workaround{}" c.Expr[Any](Block( List( @@ -48,5 +48,5 @@ object Macros { } object mkObject { - def apply(xs: Any*) = macro Macros.mkObjectImpl + def apply(xs: Any*): Any = macro Macros.mkObjectImpl } diff --git a/test/files/run/macro-whitebox-extractor/Macros_1.scala b/test/files/run/macro-whitebox-extractor/Macros_1.scala index 4a1138fc9d..64053b8a24 100644 --- a/test/files/run/macro-whitebox-extractor/Macros_1.scala +++ b/test/files/run/macro-whitebox-extractor/Macros_1.scala @@ -2,7 +2,7 @@ import scala.reflect.macros.WhiteboxContext import language.experimental.macros object Extractor { - def unapply(x: Int) = macro Macros.unapplyImpl + def unapply(x: Int): Any = macro Macros.unapplyImpl } object Macros { diff --git a/test/files/run/macro-whitebox-structural/Impls_Macros_1.scala b/test/files/run/macro-whitebox-structural/Impls_Macros_1.scala index 1b975ca850..b8d0c042be 100644 --- a/test/files/run/macro-whitebox-structural/Impls_Macros_1.scala +++ b/test/files/run/macro-whitebox-structural/Impls_Macros_1.scala @@ -12,5 +12,5 @@ object Macros { """ } - def foo = macro impl + def foo: Any = macro impl }
\ No newline at end of file diff --git a/test/files/run/repl-term-macros.check b/test/files/run/repl-term-macros.check index 64c46392a3..f73abb5dc3 100644 --- a/test/files/run/repl-term-macros.check +++ b/test/files/run/repl-term-macros.check @@ -12,7 +12,7 @@ scala> scala> def impl1(c: BlackboxContext) = { import c.universe._; c.Expr[Unit](q"()") } impl1: (c: scala.reflect.macros.BlackboxContext)c.Expr[Unit] -scala> def foo1 = macro impl1 +scala> def foo1: Unit = macro impl1 defined term macro foo1: Unit scala> foo1 @@ -22,7 +22,7 @@ scala> scala> def impl2(c: BlackboxContext)() = { import c.universe._; c.Expr[Unit](q"()") } impl2: (c: scala.reflect.macros.BlackboxContext)()c.Expr[Unit] -scala> def foo2() = macro impl2 +scala> def foo2(): Unit = macro impl2 defined term macro foo2: ()Unit scala> foo2() @@ -32,7 +32,7 @@ scala> scala> def impl3(c: BlackboxContext)(x: c.Expr[Int])(y: c.Expr[Int]) = { import c.universe._; c.Expr[Unit](q"()") } impl3: (c: scala.reflect.macros.BlackboxContext)(x: c.Expr[Int])(y: c.Expr[Int])c.Expr[Unit] -scala> def foo3(x: Int)(y: Int) = macro impl3 +scala> def foo3(x: Int)(y: Int): Unit = macro impl3 defined term macro foo3: (x: Int)(y: Int)Unit scala> foo3(2)(3) diff --git a/test/files/run/repl-term-macros.scala b/test/files/run/repl-term-macros.scala index a779638c00..b4660e258e 100644 --- a/test/files/run/repl-term-macros.scala +++ b/test/files/run/repl-term-macros.scala @@ -6,15 +6,15 @@ object Test extends ReplTest { import language.experimental.macros def impl1(c: BlackboxContext) = { import c.universe._; c.Expr[Unit](q"()") } -def foo1 = macro impl1 +def foo1: Unit = macro impl1 foo1 def impl2(c: BlackboxContext)() = { import c.universe._; c.Expr[Unit](q"()") } -def foo2() = macro impl2 +def foo2(): Unit = macro impl2 foo2() def impl3(c: BlackboxContext)(x: c.Expr[Int])(y: c.Expr[Int]) = { import c.universe._; c.Expr[Unit](q"()") } -def foo3(x: Int)(y: Int) = macro impl3 +def foo3(x: Int)(y: Int): Unit = macro impl3 foo3(2)(3) """ }
\ No newline at end of file diff --git a/test/files/run/t4841-isolate-plugins.check b/test/files/run/t4841-isolate-plugins.check new file mode 100644 index 0000000000..a6462b424b --- /dev/null +++ b/test/files/run/t4841-isolate-plugins.check @@ -0,0 +1,2 @@ +My phase name is ploogin1_1 +My phase name is ploogin1_2 diff --git a/test/files/run/t4841-isolate-plugins/ploogin.scala b/test/files/run/t4841-isolate-plugins/ploogin.scala new file mode 100644 index 0000000000..bd8c7275ec --- /dev/null +++ b/test/files/run/t4841-isolate-plugins/ploogin.scala @@ -0,0 +1,30 @@ + +package t4841 + +import scala.tools.nsc.{ Global, Phase } +import scala.tools.nsc.plugins.{ Plugin, PluginComponent } +import scala.reflect.io.Path +import scala.reflect.io.File + +/** A test plugin. */ +class Ploogin(val global: Global, val name: String = "ploogin") extends Plugin { + import global._ + + val description = "A sample plugin for testing." + val components = List[PluginComponent](TestComponent) + + private object TestComponent extends PluginComponent { + val global: Ploogin.this.global.type = Ploogin.this.global + //override val runsBefore = List("refchecks") + val runsAfter = List("jvm") + val phaseName = Ploogin.this.name + override def description = "A sample phase that does so many things it's kind of hard to describe briefly." + def newPhase(prev: Phase) = new TestPhase(prev) + class TestPhase(prev: Phase) extends StdPhase(prev) { + override def description = TestComponent.this.description + def apply(unit: CompilationUnit) { + if (settings.developer) inform(s"My phase name is $phaseName") + } + } + } +} diff --git a/test/files/run/t4841-isolate-plugins/t4841-isolate-plugin.scala b/test/files/run/t4841-isolate-plugins/t4841-isolate-plugin.scala new file mode 100644 index 0000000000..5421922c9c --- /dev/null +++ b/test/files/run/t4841-isolate-plugins/t4841-isolate-plugin.scala @@ -0,0 +1,39 @@ + +import tools.nsc.plugins.PluginDescription +import tools.partest.DirectTest + +import java.io.File + +// show that plugins are on isolated class loaders +object Test extends DirectTest { + override def code = "class Code" + + override def extraSettings = s"-usejavacp" + + // plugin named ploogin1_1 or ploogin1_2, but not ploogin2_x + // Although the samples are in different classloaders, the plugin + // loader checks for distinctness by class name, so the names must differ. + def pluginCode(index: Int) = s""" + |package t4841 { + | class SamplePloogin$index(global: scala.tools.nsc.Global) extends Ploogin(global, s"$${PlooginCounter.named}_$index") + | object PlooginCounter { + | val count = new java.util.concurrent.atomic.AtomicInteger + | def named = s"ploogin$${count.incrementAndGet}" + | } + |}""".stripMargin.trim + + def compilePlugin(i: Int) = { + val out = (testOutput / s"p$i").createDirectory() + val args = Seq("-usejavacp", "-d", out.path) + compileString(newCompiler(args: _*))(pluginCode(i)) + val xml = PluginDescription(s"p$i", s"t4841.SamplePloogin$i").toXML + (out / "scalac-plugin.xml").toFile writeAll xml + out + } + + override def show() = { + val dirs = 1 to 2 map (compilePlugin(_)) + compile("-Xdev", s"-Xplugin:${dirs mkString ","}", "-usejavacp", "-d", testOutput.path) + } +} + diff --git a/test/files/run/t4841-no-plugin.check b/test/files/run/t4841-no-plugin.check new file mode 100644 index 0000000000..4338f0ce23 --- /dev/null +++ b/test/files/run/t4841-no-plugin.check @@ -0,0 +1 @@ +warning: No plugin in path t4841-no-plugin-run.obj/plugins.partest diff --git a/test/files/run/t4841-no-plugin.scala b/test/files/run/t4841-no-plugin.scala new file mode 100644 index 0000000000..d91bf7ee21 --- /dev/null +++ b/test/files/run/t4841-no-plugin.scala @@ -0,0 +1,17 @@ + +import tools.partest.DirectTest + +import java.io.File + +// warn only if no plugin on Xplugin path +object Test extends DirectTest { + override def code = "class Code" + + override def extraSettings = s"-usejavacp -d ${testOutput.path}" + + override def show() = { + val tmp = new File(testOutput.jfile, "plugins.partest").getAbsolutePath + compile("-Xdev", s"-Xplugin:$tmp", "-Xpluginsdir", tmp) + } +} + diff --git a/test/files/run/t5894.scala b/test/files/run/t5894.scala index 55767d8889..5d482333f5 100644 --- a/test/files/run/t5894.scala +++ b/test/files/run/t5894.scala @@ -3,7 +3,7 @@ import language.experimental.macros class Test object Test { - def foo = macro fooImpl + def foo: Unit = macro fooImpl def fooImpl(c: reflect.macros.BlackboxContext) = { import c.universe._; c.Expr[Unit](q"()") } def main(args: Array[String]) { diff --git a/test/files/run/t5903a/Macros_1.scala b/test/files/run/t5903a/Macros_1.scala index 7888b888e1..ce1b035260 100644 --- a/test/files/run/t5903a/Macros_1.scala +++ b/test/files/run/t5903a/Macros_1.scala @@ -7,7 +7,7 @@ case object SomeTree extends Tree object NewQuasiquotes { implicit class QuasiquoteInterpolation(c: StringContext) { object nq { - def unapply(t: Tree) = macro QuasiquoteMacros.unapplyImpl + def unapply(t: Tree): Any = macro QuasiquoteMacros.unapplyImpl } } } diff --git a/test/files/run/t5903b/Macros_1.scala b/test/files/run/t5903b/Macros_1.scala index 8c03e5579d..97f15cec3b 100644 --- a/test/files/run/t5903b/Macros_1.scala +++ b/test/files/run/t5903b/Macros_1.scala @@ -4,7 +4,7 @@ import language.experimental.macros object Interpolation { implicit class TestInterpolation(c: StringContext) { object t { - def unapply[T](x: T) = macro Macros.unapplyImpl[T] + def unapply[T](x: T): Any = macro Macros.unapplyImpl[T] } } } diff --git a/test/files/run/t5903c/Macros_1.scala b/test/files/run/t5903c/Macros_1.scala index c9dfe9d60c..979284a263 100644 --- a/test/files/run/t5903c/Macros_1.scala +++ b/test/files/run/t5903c/Macros_1.scala @@ -4,7 +4,7 @@ import language.experimental.macros object Interpolation { implicit class TestInterpolation(c: StringContext) { object t { - def unapply[T](x: T) = macro Macros.unapplyImpl[T] + def unapply[T](x: T): Any = macro Macros.unapplyImpl[T] } } } diff --git a/test/files/run/t5903d/Macros_1.scala b/test/files/run/t5903d/Macros_1.scala index 8a57e27602..dc1989462b 100644 --- a/test/files/run/t5903d/Macros_1.scala +++ b/test/files/run/t5903d/Macros_1.scala @@ -4,7 +4,7 @@ import language.experimental.macros object Interpolation { implicit class TestInterpolation(c: StringContext) { object t { - def unapply(x: Int) = macro Macros.unapplyImpl + def unapply(x: Int): Any = macro Macros.unapplyImpl } } } diff --git a/test/files/run/t5940.scala b/test/files/run/t5940.scala index d98f267123..062f11c467 100644 --- a/test/files/run/t5940.scala +++ b/test/files/run/t5940.scala @@ -13,7 +13,7 @@ object Test extends DirectTest { object Macros { //import Impls._ def impl(c: BlackboxContext) = { import c.universe._; c.Expr[Unit](q"()") } - def foo = macro impl + def foo: Unit = macro impl } """ def compileMacros() = { diff --git a/test/files/run/t6381.check b/test/files/run/t6381.check index dfc9d44850..ef08d0da09 100644 --- a/test/files/run/t6381.check +++ b/test/files/run/t6381.check @@ -10,7 +10,7 @@ scala> def pos_impl(c: reflect.macros.BlackboxContext): c.Expr[String] = { } pos_impl: (c: scala.reflect.macros.BlackboxContext)c.Expr[String] -scala> def pos = macro pos_impl +scala> def pos: String = macro pos_impl defined term macro pos: String scala> pos diff --git a/test/files/run/t6381.scala b/test/files/run/t6381.scala index 0e2264d8fa..c78dc13ed7 100644 --- a/test/files/run/t6381.scala +++ b/test/files/run/t6381.scala @@ -7,7 +7,7 @@ object Test extends ReplTest { | import c.universe._ | c.Expr[String](Literal(Constant(c.enclosingPosition.getClass.toString))) |} - |def pos = macro pos_impl + |def pos: String = macro pos_impl |pos |""".stripMargin.trim diff --git a/test/files/run/t7617b/Test_2.scala b/test/files/run/t7617b/Test_2.scala index e27f650e80..e1d9acdc31 100644 --- a/test/files/run/t7617b/Test_2.scala +++ b/test/files/run/t7617b/Test_2.scala @@ -2,7 +2,7 @@ import scala.language.dynamics import language.experimental.macros class C extends Dynamic { - def updateDynamic(name: String)(value: Any) = macro Macros.impl + def updateDynamic(name: String)(value: Any): Unit = macro Macros.impl } object Test extends App { diff --git a/test/files/run/t7871/Macros_1.scala b/test/files/run/t7871/Macros_1.scala index 778068deb3..801a6af4e7 100644 --- a/test/files/run/t7871/Macros_1.scala +++ b/test/files/run/t7871/Macros_1.scala @@ -7,7 +7,7 @@ case object SomeTree extends Tree object NewQuasiquotes { implicit class QuasiquoteInterpolation(c: StringContext) { object nq { - def unapply(t: Tree) = macro QuasiquoteMacros.unapplyImpl + def unapply(t: Tree): Any = macro QuasiquoteMacros.unapplyImpl } } } diff --git a/test/files/run/t7912.scala b/test/files/run/t7912.scala new file mode 100644 index 0000000000..3d603e0e97 --- /dev/null +++ b/test/files/run/t7912.scala @@ -0,0 +1,16 @@ +case object A { override def toString = ??? } + +object Test { + def foo: Int = (A: Any) match { + case 0 => 0 + } + def main(args: Array[String]): Unit = { + try { + foo + sys.error("no exception") + } catch { + case me: MatchError => assert(me.getMessage == "an instance of class A$", me.getMessage) + case ex: Throwable => sys.error("not a match error: " + ex.getClass) + } + } +} diff --git a/test/files/run/t8010.scala b/test/files/run/t8010.scala new file mode 100644 index 0000000000..8636bbd12e --- /dev/null +++ b/test/files/run/t8010.scala @@ -0,0 +1,22 @@ +trait Base { + def t = 1 + def t(n: Int) = n + def bt = 2 + def bt(n: Int) = n +} +trait Derived extends Base { + // was: double defintion error + override def t = 1 + super.t + override def t(n: Int) = 1 + super.t(n) + override def bt = 1 + super.bt + override def bt(n: Int) = 1 + super.bt(n) +} + +object Test extends App { + val d = new Derived {} + // not the focus of thie bug, but let's just check the runtime behaviour while we're here. + assert(d.t == 2) + assert(d.t(1) == 2) + assert(d.bt == 3) + assert(d.bt(1) == 2) +} diff --git a/test/files/run/t8029.scala b/test/files/run/t8029.scala new file mode 100644 index 0000000000..dbd5c41387 --- /dev/null +++ b/test/files/run/t8029.scala @@ -0,0 +1,57 @@ +import scala.tools.partest._ +import scala.tools.nsc._ + +object Test extends DirectTest { + + override def extraSettings: String = "-usejavacp -nowarn -Ystop-after:typer" + + override def code = "" // not used + + def code1 = """ +package object p1 { + trait A + object A +} + """ + + def code2 = """ +package object p2 { + class A + object A +} + """ + + def code3 = """ +package object p3 { + object A + trait A +} + """ + + def code4 = """ +package object p4 { + object A + trait A +} + """ + + def show() { + val global = newCompiler() + import global._ + def typecheck(code: String): Unit = { + val r = new Run + val sourceFile = newSources(code).head + global.reporter.reset() + r.compileSources(sourceFile :: Nil) + assert(!global.reporter.hasErrors) + } + + def typecheckTwice(code: String): Unit = { + typecheck(code) + typecheck(code) + } + + // was: illegal cyclic reference involving package ... + Seq(code1, code2, code3, code4) foreach typecheckTwice + } +} diff --git a/test/files/run/toolbox_current_run_compiles.scala b/test/files/run/toolbox_current_run_compiles.scala index bc6a9d343e..31e0a45eea 100644 --- a/test/files/run/toolbox_current_run_compiles.scala +++ b/test/files/run/toolbox_current_run_compiles.scala @@ -9,7 +9,7 @@ package pkg { val g = c.universe.asInstanceOf[scala.tools.nsc.Global] c.Expr[Boolean](Literal(Constant(g.currentRun.compiles(sym.asInstanceOf[g.Symbol])))) } - def compiles[T] = macro impl[T] + def compiles[T]: Boolean = macro impl[T] } } diff --git a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala index 7905a2ca15..c5cac3ea45 100644 --- a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala +++ b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala @@ -1,5 +1,4 @@ import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.api.{Liftable, Universe} import scala.reflect.runtime.universe._, Flag._ trait ArbitraryTreesAndNames { @@ -265,14 +264,8 @@ trait ArbitraryTreesAndNames { def genTreeIsTypeWrapped(size: Int) = for(tit <- genTreeIsType(size)) yield TreeIsType(tit) - implicit object liftTreeIsTerm extends Liftable[TreeIsTerm] { - def apply(universe: Universe, value: TreeIsTerm): universe.Tree = - value.tree.asInstanceOf[universe.Tree] - } - implicit object liftTreeIsType extends Liftable[TreeIsType] { - def apply(universe: Universe, value: TreeIsType): universe.Tree = - value.tree.asInstanceOf[universe.Tree] - } + implicit val liftTreeIsTerm = Liftable[TreeIsTerm] { _.tree } + implicit val liftTreeIsType = Liftable[TreeIsType] { _.tree } implicit def treeIsTerm2tree(tit: TreeIsTerm): Tree = tit.tree implicit def treeIsType2tree(tit: TreeIsType): Tree = tit.tree diff --git a/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala index 2ec679e78b..2af656c7c9 100644 --- a/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala @@ -2,12 +2,25 @@ import org.scalacheck._, Prop._, Gen._, Arbitrary._ import scala.reflect.runtime.universe._, Flag._, build.ScalaDot object DefinitionConstructionProps - extends QuasiquoteProperties("definition construction") - with ClassConstruction - with TraitConstruction - with TypeDefConstruction - with ValDefConstruction - with PackageConstruction + extends QuasiquoteProperties("definition construction") + with ClassConstruction + with TraitConstruction + with TypeDefConstruction + with ValDefConstruction + with PackageConstruction { + property("SI-6842") = test { + val x: Tree = q"val x: Int" + assertEqAst(q"def f($x) = 0", "def f(x: Int) = 0") + assertEqAst(q"class C($x)", "class C(val x: Int)") + assertEqAst(q"class C { $x => }", "class C { x: Int => }") + assertEqAst(q"trait B { $x => }", "trait B { x: Int => }") + assertEqAst(q"object A { $x => }", "object A { x: Int => }") + val t: Tree = q"type T" + assertEqAst(q"def f[$t] = 0", "def f[T] = 0") + assertEqAst(q"class C[$t]", "class C[T]") + assertEqAst(q"trait B[$t]", "trait B[T]") + } +} trait ClassConstruction { self: QuasiquoteProperties => val anyRef = ScalaDot(TypeName("AnyRef")) @@ -283,7 +296,7 @@ trait MethodConstruction { self: QuasiquoteProperties => assertEqAst(q"@$a def foo", "@Foo[A,B] def foo") } - property("splice annotation with multiple argument lists") = test{ + property("splice annotation with multiple argument lists") = test { val a = q"new Foo(a)(b)" assertEqAst(q"@$a def foo", "@Foo(a)(b) def foo") } diff --git a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala index dbd26bf72a..94465930ed 100644 --- a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala @@ -88,6 +88,22 @@ trait ClassDeconstruction { self: QuasiquoteProperties => matches("class Foo { self => bar(self) }") matches("case class Foo(x: Int)") } + + property("SI-7979") = test { + val PARAMACCESSOR = (1 << 29).toLong.asInstanceOf[FlagSet] + assertThrows[MatchError] { + val build.SyntacticClassDef(_, _, _, _, _, _, _, _, _) = + ClassDef( + Modifiers(), TypeName("Foo"), List(), + Template( + List(Select(Ident(TermName("scala")), TypeName("AnyRef"))), + noSelfType, + List( + //ValDef(Modifiers(PRIVATE | LOCAL | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree), + DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"), + Ident(TypeName("Int")), EmptyTree))), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(()))))))) + } + } } trait ModsDeconstruction { self: QuasiquoteProperties => diff --git a/test/files/scalacheck/quasiquotes/ErrorProps.scala b/test/files/scalacheck/quasiquotes/ErrorProps.scala index cb46a60dbe..92d299bede 100644 --- a/test/files/scalacheck/quasiquotes/ErrorProps.scala +++ b/test/files/scalacheck/quasiquotes/ErrorProps.scala @@ -105,13 +105,6 @@ object ErrorProps extends QuasiquoteProperties("errors") { q"f($sb)" """) - property("casedef expected") = fails( - "reflect.runtime.universe.CaseDef expected but reflect.runtime.universe.Tree found", - """ - val t = EmptyTree - q"_ { case $t }" - """) - property("can't splice with ... card here") = fails( "Can't splice with ... here", """ @@ -179,6 +172,20 @@ object ErrorProps extends QuasiquoteProperties("errors") { val q"$m1 $m2 def foo" = EmptyTree """) + property("can't splice values of Null") = fails( + "Can't splice Null, bottom type values often indicate programmer mistake", + """ + val n = null + q"$n" + """) + + property("can't splice values of Nothing") = fails( + "Can't splice Nothing, bottom type values often indicate programmer mistake", + """ + def n = ??? + q"$n" + """) + // // Make sure a nice error is reported in this case // { import Flag._; val mods = NoMods; q"lazy $mods val x: Int" } }
\ No newline at end of file diff --git a/test/files/scalacheck/quasiquotes/LiftableProps.scala b/test/files/scalacheck/quasiquotes/LiftableProps.scala index 1271e1accd..539375d905 100644 --- a/test/files/scalacheck/quasiquotes/LiftableProps.scala +++ b/test/files/scalacheck/quasiquotes/LiftableProps.scala @@ -76,4 +76,39 @@ object LiftableProps extends QuasiquoteProperties("liftable") { val const = Constant(0) assert(q"$const" ≈ q"0") } + + property("lift list variants") = test { + val lst = List(1, 2) + val immutable = q"$scalapkg.collection.immutable" + assert(q"$lst" ≈ q"$immutable.List(1, 2)") + assert(q"f(..$lst)" ≈ q"f(1, 2)") + val llst = List(List(1), List(2)) + assert(q"f(..$llst)" ≈ q"f($immutable.List(1), $immutable.List(2))") + assert(q"f(...$llst)" ≈ q"f(1)(2)") + } + + property("lift tuple") = test { + assert(q"${Tuple1(1)}" ≈ q"scala.Tuple1(1)") + assert(q"${(1, 2)}" ≈ q"(1, 2)") + assert(q"${(1, 2, 3)}" ≈ q"(1, 2, 3)") + assert(q"${(1, 2, 3, 4)}" ≈ q"(1, 2, 3, 4)") + assert(q"${(1, 2, 3, 4, 5)}" ≈ q"(1, 2, 3, 4, 5)") + assert(q"${(1, 2, 3, 4, 5, 6)}" ≈ q"(1, 2, 3, 4, 5, 6)") + assert(q"${(1, 2, 3, 4, 5, 6, 7)}" ≈ q"(1, 2, 3, 4, 5, 6, 7)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)") + assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)") + } }
\ No newline at end of file diff --git a/test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala b/test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala index b331c4b6b6..5411e664a2 100644 --- a/test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala +++ b/test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala @@ -120,4 +120,6 @@ trait Helpers { def annot(name: TypeName): Tree = annot(name, Nil) def annot(name: String, args: List[Tree]): Tree = annot(TypeName(name), args) def annot(name: TypeName, args: List[Tree]): Tree = q"new $name(..$args)" -}
\ No newline at end of file + + val scalapkg = build.setSymbol(Ident(TermName("scala")), definitions.ScalaPackage) +} diff --git a/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala b/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala new file mode 100644 index 0000000000..a3b6137f68 --- /dev/null +++ b/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala @@ -0,0 +1,75 @@ +import org.scalacheck._, Prop._, Gen._, Arbitrary._ +import scala.reflect.runtime.universe._, Flag._ + +object RuntimeErrorProps extends QuasiquoteProperties("errors") { + def testFails[T](block: =>T) = test { + assertThrows[IllegalArgumentException] { + block + } + } + + property("default param anon function") = testFails { + val param = q"val x: Int = 1" + q"{ $param => x + 1 }" + } + + property("non-casedef case") = testFails { + val x = q"x" + q"foo match { case $x }" + } + + property("non-new annotation") = testFails { + val annot = q"foo" + q"@$annot def foo" + } + + property("non-valdef param") = testFails { + val param = q"foo" + q"def foo($param)" + } + + property("non-valdef class param") = testFails { + val param = q"foo" + q"class Foo($param)" + } + + property("non-typedef type param") = testFails { + val tparam = tq"T" + q"class C[$tparam]" + } + + property("non-definition refine stat") = testFails { + val stat = q"foo" + tq"Foo { $stat }" + } + + property("non-definition early def") = testFails { + val stat = q"foo" + q"class Foo extends { $stat } with Bar" + } + + property("type apply for definition") = testFails { + val defn = q"def foo" + q"$defn[foo]" + } + + property("non-val selftype") = testFails { + val foo = q"foo" + q"class Foo { $foo => }" + } + + property("for empty enums") = testFails { + val enums = List.empty[Tree] + q"for(..$enums) 0" + } + + property("for starts with non-from enum") = testFails { + val enums = fq"foo = bar" :: Nil + q"for(..$enums) 0" + } + + property("for inlalid enum") = testFails { + val enums = q"foo" :: Nil + q"for(..$enums) 0" + } +} diff --git a/test/files/scalacheck/quasiquotes/TermConstructionProps.scala b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala index cdd96205de..6fb05ff9a4 100644 --- a/test/files/scalacheck/quasiquotes/TermConstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/TermConstructionProps.scala @@ -203,4 +203,25 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") { assert(q"f(..${l1 ++ l2}, $baz)" ≈ q"f(foo, bar, baz)") assert(q"f(${if (true) q"a" else q"b"})" ≈ q"f(a)") } + + property("splice iterable of non-parametric type") = test { + object O extends Iterable[Tree] { def iterator = List(q"foo").iterator } + q"f(..$O)" + } + + property("SI-8016") = test { + val xs = q"1" :: q"2" :: Nil + assertEqAst(q"..$xs", "{1; 2}") + assertEqAst(q"{..$xs}", "{1; 2}") + } + + property("SI-6842") = test { + val cases: List[Tree] = cq"a => b" :: cq"_ => c" :: Nil + assertEqAst(q"1 match { case ..$cases }", "1 match { case a => b case _ => c }") + assertEqAst(q"try 1 catch { case ..$cases }", "try 1 catch { case a => b case _ => c }") + } + + property("SI-8009") = test { + q"`foo`".asInstanceOf[reflect.internal.SymbolTable#Ident].isBackquoted + } } diff --git a/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala index bd81afa125..8d1ada342a 100644 --- a/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala @@ -3,8 +3,10 @@ import scala.reflect.runtime.universe._, Flag._ object TermDeconstructionProps extends QuasiquoteProperties("term deconstruction") { property("f(..x) = f") = test { - val q"f(..$args)" = q"f" - assert(args ≈ Nil) + // see SI-8008 + assertThrows[MatchError] { + val q"f(..$args)" = q"f" + } } property("f(x)") = forAll { (x: Tree) => diff --git a/test/files/scalacheck/quasiquotes/Test.scala b/test/files/scalacheck/quasiquotes/Test.scala index 8b1e779ab2..7a26fa4923 100644 --- a/test/files/scalacheck/quasiquotes/Test.scala +++ b/test/files/scalacheck/quasiquotes/Test.scala @@ -8,7 +8,9 @@ object Test extends Properties("quasiquotes") { include(PatternConstructionProps) include(PatternDeconstructionProps) include(LiftableProps) + include(UnliftableProps) include(ErrorProps) + include(RuntimeErrorProps) include(DefinitionConstructionProps) include(DefinitionDeconstructionProps) include(DeprecationProps) diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala index f443330e0b..2f501435e3 100644 --- a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala +++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala @@ -50,4 +50,29 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") { assert(enums1 ≈ enums) assert(body1 ≈ body) } + + property("extract UnApply (1)") = test { + val q"object $_ { $_; $_; $m }" = typecheck(q""" + object Test { + class Cell(val x: Int) + object Cell { def unapply(c: Cell) = Some(c.x) } + new Cell(0) match { case Cell(v) => v } + } + """) + val q"$_ match { case $f(..$args) => $_ }" = m + assert(f ≈ pq"Test.this.Cell") + assert(args ≈ List(pq"v")) + } + + property("extract UnApply (2)") = test { + val q"object $_ { $_; $_; $m }" = typecheck(q""" + object Test { + case class Cell(val x: Int) + new Cell(0) match { case Cell(v) => v } + } + """) + val q"$_ match { case ${f: TypeTree}(..$args) => $_ }" = m + assert(f.original ≈ pq"Test.this.Cell") + assert(args ≈ List(pq"v")) + } }
\ No newline at end of file diff --git a/test/files/scalacheck/quasiquotes/UnliftableProps.scala b/test/files/scalacheck/quasiquotes/UnliftableProps.scala new file mode 100644 index 0000000000..8b827c98ff --- /dev/null +++ b/test/files/scalacheck/quasiquotes/UnliftableProps.scala @@ -0,0 +1,160 @@ +import org.scalacheck._, Prop._, Gen._, Arbitrary._ +import scala.reflect.runtime.universe._, Flag._ + +object UnliftableProps extends QuasiquoteProperties("unliftable") { + property("unlift name") = test { + val termname0 = TermName("foo") + val typename0 = TypeName("foo") + val q"${termname1: TermName}" = Ident(termname0) + assert(termname1 == termname0) + val q"${typename1: TypeName}" = Ident(typename0) + assert(typename1 == typename0) + val q"${name1: Name}" = Ident(termname0) + assert(name1 == termname0) + val q"${name2: Name}" = Ident(typename0) + assert(name2 == typename0) + } + + property("unlift type") = test { + val q"${tpe: Type}" = TypeTree(typeOf[Int]) + assert(tpe =:= typeOf[Int]) + } + + property("unlift constant") = test { + val q"${const: Constant}" = Literal(Constant("foo")) + assert(const == Constant("foo")) + } + + property("unlift char") = test { + val q"${c: Char}" = Literal(Constant('0')) + assert(c.isInstanceOf[Char] && c == '0') + } + + property("unlift byte") = test { + val q"${b: Byte}" = Literal(Constant(0: Byte)) + assert(b.isInstanceOf[Byte] && b == 0) + } + + property("unlift short") = test { + val q"${s: Short}" = Literal(Constant(0: Short)) + assert(s.isInstanceOf[Short] && s == 0) + } + + property("unlift int") = test { + val q"${i: Int}" = Literal(Constant(0: Int)) + assert(i.isInstanceOf[Int] && i == 0) + } + + property("unlift long") = test { + val q"${l: Long}" = Literal(Constant(0L: Long)) + assert(l.isInstanceOf[Long] && l == 0L) + } + + property("unlift float") = test { + val q"${f: Float}" = Literal(Constant(0.0f: Float)) + assert(f.isInstanceOf[Float] && f == 0.0f) + } + + property("unlift double") = test { + val q"${d: Double}" = Literal(Constant(0.0: Double)) + assert(d.isInstanceOf[Double] && d == 0.0) + } + + property("unlift bool") = test { + val q"${b: Boolean}" = q"true" + assert(b.isInstanceOf[Boolean] && b == true) + } + + property("unlift string") = test { + val q"${s: String}" = q""" "foo" """ + assert(s.isInstanceOf[String] && s == "foo") + } + + property("unlift scala.symbol") = test { + val q"${s: scala.Symbol}" = q"'foo" + assert(s.isInstanceOf[scala.Symbol] && s == 'foo) + } + + implicit def unliftList[T: Unliftable]: Unliftable[List[T]] = Unliftable { + case q"scala.collection.immutable.List(..$args)" if args.forall { implicitly[Unliftable[T]].unapply(_).nonEmpty } => + val ut = implicitly[Unliftable[T]] + args.flatMap { ut.unapply(_) } + } + + property("unlift list (1)") = test { + val orig = List(1, 2) + val q"${l1: List[Int]}" = q"$orig" // q"List(1, 2)" + assert(l1 == orig) + val q"f(..${l2: List[Int]})" = q"f(..$orig)" // q"f(1, 2) + assert(l2 == orig) + } + + property("unlift list (2)") = test { + val orig2 = List(List(1, 2), List(3)) + val q"f(${l3: List[List[Int]]})" = q"f($orig2)" // q"f(List(List(1, 2), List(3))) + assert(l3 == orig2) + val q"f(..${l4: List[List[Int]]})" = q"f(..$orig2)" // q"f(List(1, 2), List(3))" + assert(l4 == orig2) + val q"f(...${l5: List[List[Int]]})" = q"f(...$orig2)" // q"f(1, 2)(3) + assert(l5 == orig2) + } + + property("don't unlift non-tree splicee (1)") = test { + val q"${a: TermName}.${b: TermName}" = q"a.b" + assert(a == TermName("a")) + assert(b == TermName("b")) + } + + property("don't unlift non-tree splicee (2)") = test { + val q"${mods: Modifiers} def foo" = q"def foo" + assert(mods == Modifiers(DEFERRED)) + } + + property("unlift tuple") = test { + // fails due to SI-8045 + // val q"${t1: Tuple1[Int]}" = q"_root_.scala.Tuple1(1)" + val q"${t2: (Int, Int)}" = q"(1, 2)" + val q"${t3: (Int, Int, Int)}" = q"(1, 2, 3)" + val q"${t4: (Int, Int, Int, Int)}" = q"(1, 2, 3, 4)" + val q"${t5: (Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5)" + val q"${t6: (Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6)" + val q"${t7: (Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7)" + val q"${t8: (Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8)" + val q"${t9: (Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9)" + val q"${t10: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)" + val q"${t11: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)" + val q"${t12: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)" + val q"${t13: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)" + val q"${t14: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)" + val q"${t15: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)" + val q"${t16: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)" + val q"${t17: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)" + val q"${t18: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)" + val q"${t19: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)" + val q"${t20: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)" + val q"${t21: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)" + val q"${t22: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)}" = q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)" + // assert(t1 == Tuple1(1)) + assert(t2 == (1, 2)) + assert(t3 == (1, 2, 3)) + assert(t4 == (1, 2, 3, 4)) + assert(t5 == (1, 2, 3, 4, 5)) + assert(t6 == (1, 2, 3, 4, 5, 6)) + assert(t7 == (1, 2, 3, 4, 5, 6, 7)) + assert(t8 == (1, 2, 3, 4, 5, 6, 7, 8)) + assert(t9 == (1, 2, 3, 4, 5, 6, 7, 8, 9)) + assert(t10 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) + assert(t11 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)) + assert(t12 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)) + assert(t13 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)) + assert(t14 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)) + assert(t15 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) + assert(t16 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)) + assert(t17 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)) + assert(t18 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)) + assert(t19 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)) + assert(t20 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)) + assert(t21 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)) + assert(t22 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)) + } +} diff --git a/test/junit/scala/collection/QueueTest.scala b/test/junit/scala/collection/QueueTest.scala new file mode 100644 index 0000000000..9a40d8fc90 --- /dev/null +++ b/test/junit/scala/collection/QueueTest.scala @@ -0,0 +1,28 @@ +package scala.collection.immutable + +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.Test + +@RunWith(classOf[JUnit4]) +/* Tests for collection.immutable.Queue */ +class QueueTest { + val emptyQueue = Queue.empty[Int] + val oneAdded = emptyQueue.enqueue(1) + val threeAdded = emptyQueue.enqueue(1 to 3) + + @Test + def dequeueOptionOnEmpty() { + assert( emptyQueue.dequeueOption == None ) + } + + @Test + def dequeueOptionOneAdded() { + assert( oneAdded.dequeueOption == Some((1,emptyQueue)) ) + } + + @Test + def dequeueOptionThreeAdded() { + assert( threeAdded.dequeueOption == Some((1,Queue(2 to 3:_*))) ) + } +} diff --git a/test/junit/scala/reflect/internal/util/StringOpsTest.scala b/test/junit/scala/reflect/internal/util/StringOpsTest.scala new file mode 100644 index 0000000000..13d3a6435e --- /dev/null +++ b/test/junit/scala/reflect/internal/util/StringOpsTest.scala @@ -0,0 +1,52 @@ +package scala.reflect.internal.util + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class StringOpsTest { + @Test + def prefixOfNone(): Unit = { + val so = new StringOps { } + val ss = Nil + val lcp = so longestCommonPrefix ss + assert(lcp == "") + } + @Test + def prefixWithEmpty(): Unit = { + val so = new StringOps { } + val ss = List("abc", "", "abd") + val lcp = so longestCommonPrefix ss + assert(lcp == "") + } + @Test + def prefixOfOne(): Unit = { + val so = new StringOps { } + val ss = List("abc") + val lcp = so longestCommonPrefix ss + assert(lcp == "abc") + } + @Test + def prefixOfMany(): Unit = { + val so = new StringOps { } + val ss = List("abc", "abd", "abe") + val lcp = so longestCommonPrefix ss + assert(lcp == "ab") + } + @Test + def prefixOfPrefix(): Unit = { + val so = new StringOps { } + val ss = List("abc", "abcd") + val lcp = so longestCommonPrefix ss + assert(lcp == "abc") + } + @Test + def prefixOfPrefixMiddling(): Unit = { + val so = new StringOps { } + val ss = List("abce", "abc", "abcd") + val lcp = so longestCommonPrefix ss + assert(lcp == "abc") + } +} diff --git a/test/scaladoc/run/SI-6812.scala b/test/scaladoc/run/SI-6812.scala index fbd9588ede..059c327e7e 100644 --- a/test/scaladoc/run/SI-6812.scala +++ b/test/scaladoc/run/SI-6812.scala @@ -5,12 +5,12 @@ import language._ object Test extends ScaladocModelTest { override def code = """ - import scala.reflect.macros.Context + import scala.reflect.macros.BlackboxContext import language.experimental.macros object Macros { - def impl(c: Context) = c.literalUnit - def foo = macro impl + def impl(c: BlackboxContext) = c.literalUnit + def foo: Unit = macro impl } class C { |