Skip to content

Preparing for Scala 2.11.0 #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Feb 21, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3f0b47c
toolboxClasspath now works for snapshots
xeno-by Feb 12, 2014
a4c3b41
silences a warning in AsyncAnalysis
xeno-by Feb 12, 2014
4a35394
migrates to 2.11.0-RC1
xeno-by Feb 15, 2014
38a85e7
using compat._ to plug source compatibility breakages
xeno-by Feb 15, 2014
2216c68
removes logic that branches on forInteractive
xeno-by Feb 14, 2014
125b300
compat => internal
xeno-by Feb 14, 2014
1b76f83
injects context into AsyncBase
xeno-by Feb 14, 2014
4bfe12d
abort => c.abort
xeno-by Feb 14, 2014
42544e7
currentUnit.freshName => c.freshName (leads to less precise tests...)
xeno-by Feb 14, 2014
aeb95bc
removes "import global._" and "def Expr" in TransformUtils
xeno-by Feb 14, 2014
2f4b6a0
eliminates all usages of global in TransformUtils
xeno-by Feb 14, 2014
2b2a0fc
cleans up LiveVariables
xeno-by Feb 14, 2014
46621c4
cleans up Lifter
xeno-by Feb 14, 2014
b792b50
cleans up FutureSystem
xeno-by Feb 14, 2014
dca99c9
cleans up ExprBuilder
xeno-by Feb 14, 2014
84b9a42
cleans up AsyncTransform
xeno-by Feb 14, 2014
393e101
cleans up AsyncAnalysis
xeno-by Feb 14, 2014
fd98325
cleans up AnfTransform
xeno-by Feb 14, 2014
defca0c
gets rid of home-grown changeOwner
xeno-by Feb 14, 2014
a14d758
replaces mkAttributedCast
xeno-by Feb 14, 2014
69f3a4d
migrates transformAt to typingTransform
xeno-by Feb 14, 2014
76c9839
migrates UseFields to typingTransform
xeno-by Feb 14, 2014
18bea76
oh God, in-place typechecking!!!
xeno-by Feb 14, 2014
7e72ef0
migrates SelectiveAnfTransform to typingTransform
xeno-by Feb 14, 2014
cc47ec1
callSiteTyper and TypingTransformers are gone
xeno-by Feb 14, 2014
ac7ba71
AsyncMacro.macroApplication is gone
xeno-by Feb 14, 2014
bc51a19
AsyncMacro.global is gone
xeno-by Feb 15, 2014
61a682f
Finalize the move to Scala 2.11.x
retronym Feb 21, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ language: scala
script:
- sbt ++$TRAVIS_SCALA_VERSION clean test publishLocal
scala:
- 2.10.3
- 2.11.0-M6
- 2.11.0-SNAPSHOT
jdk:
- openjdk6
- openjdk7
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

[![Build Status](https://secure.travis-ci.org/scala/async.png)](http://travis-ci.org/scala/async)

Note: this branch targets Scala 2.11.x, support for Scala 2.10.x has been moved to [this branch](https://github.com/scala/async/tree/2.10.x).

## Quick start

Expand Down
16 changes: 5 additions & 11 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
scalaVersion := "2.10.3"
scalaVersion := "2.11.0-SNAPSHOT"

// Uncomment to test with a locally built copy of Scala.
// scalaHome := Some(file("/code/scala2/build/pack"))

resolvers ++= (if (scalaVersion.value.endsWith("SNAPSHOT")) List(Resolver.sonatypeRepo("snapshots")) else Nil)

organization := "org.scala-lang.modules"

name := "scala-async"

version := "0.9.0-SNAPSHOT"

libraryDependencies <++= (scalaVersion) {
sv => Seq(
// TODO we should make this provided after we rely on @compileTimeOnly in scla-library in 2.11.-
// but if we do that now, and a user doesn't have this on the classpath, they can get the
// dreaded MissingRequirementErrors when unpickling types from scala.async.Async
"org.scala-lang" % "scala-reflect" % sv,
"org.scala-lang" % "scala-compiler" % sv % "provided"
)
}
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided"

libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value % "test" // for ToolBox

libraryDependencies += "junit" % "junit-dep" % "4.10" % "test"

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/scala/async/Async.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package scala.async

import scala.language.experimental.macros
import scala.concurrent.{Future, ExecutionContext}
import scala.reflect.internal.annotations.compileTimeOnly
import scala.annotation.compileTimeOnly

/**
* Async blocks provide a direct means to work with [[scala.concurrent.Future]].
Expand Down
470 changes: 233 additions & 237 deletions src/main/scala/scala/async/internal/AnfTransform.scala

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/main/scala/scala/async/internal/AsyncAnalysis.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import scala.collection.mutable
trait AsyncAnalysis {
self: AsyncMacro =>

import global._
import c.universe._

/**
* Analyze the contents of an `async` block in order to:
Expand All @@ -21,14 +21,14 @@ trait AsyncAnalysis {
def reportUnsupportedAwaits(tree: Tree): Unit = {
val analyzer = new UnsupportedAwaitAnalyzer
analyzer.traverse(tree)
analyzer.hasUnsupportedAwaits
// analyzer.hasUnsupportedAwaits // XB: not used?!
}

private class UnsupportedAwaitAnalyzer extends AsyncTraverser {
var hasUnsupportedAwaits = false

override def nestedClass(classDef: ClassDef) {
val kind = if (classDef.symbol.isTrait) "trait" else "class"
val kind = if (classDef.symbol.asClass.isTrait) "trait" else "class"
reportUnsupportedAwait(classDef, s"nested ${kind}")
}

Expand Down Expand Up @@ -59,10 +59,10 @@ trait AsyncAnalysis {
reportUnsupportedAwait(tree, "try/catch")
super.traverse(tree)
case Return(_) =>
abort(tree.pos, "return is illegal within a async block")
c.abort(tree.pos, "return is illegal within a async block")
case ValDef(mods, _, _, _) if mods.hasFlag(Flag.LAZY) =>
// TODO lift this restriction
abort(tree.pos, "lazy vals are illegal within an async block")
c.abort(tree.pos, "lazy vals are illegal within an async block")
case CaseDef(_, guard, _) if guard exists isAwait =>
// TODO lift this restriction
reportUnsupportedAwait(tree, "pattern guard")
Expand All @@ -87,7 +87,7 @@ trait AsyncAnalysis {

private def reportError(pos: Position, msg: String) {
hasUnsupportedAwaits = true
abort(pos, msg)
c.abort(pos, msg)
}
}
}
28 changes: 8 additions & 20 deletions src/main/scala/scala/async/internal/AsyncBase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,22 @@ abstract class AsyncBase {
def asyncImpl[T: c.WeakTypeTag](c: Context)
(body: c.Expr[T])
(execContext: c.Expr[futureSystem.ExecContext]): c.Expr[futureSystem.Fut[T]] = {
import c.universe._
import c.universe._, c.internal._, decorators._
val asyncMacro = AsyncMacro(c, self)

val isPresentationCompiler = asyncMacro.global.forInteractive

val code = asyncMacro.asyncTransform[T](
body.tree.asInstanceOf[asyncMacro.global.Tree],
execContext.tree.asInstanceOf[asyncMacro.global.Tree]
)(implicitly[c.WeakTypeTag[T]].asInstanceOf[asyncMacro.global.WeakTypeTag[T]]).asInstanceOf[Tree]

val code = asyncMacro.asyncTransform[T](body.tree, execContext.tree)(c.weakTypeTag[T])
AsyncUtils.vprintln(s"async state machine transform expands to:\n ${code}")
val result = if (isPresentationCompiler) {
asyncMacro.suppressExpansion()
c.macroApplication
} else {
// Mark range positions for synthetic code as transparent to allow some wiggle room for overlapping ranges
for (t <- code)
t.pos = t.pos.makeTransparent
code
}
c.Expr[futureSystem.Fut[T]](result)

// Mark range positions for synthetic code as transparent to allow some wiggle room for overlapping ranges
for (t <- code) t.setPos(t.pos.makeTransparent)
c.Expr[futureSystem.Fut[T]](code)
}

protected[async] def awaitMethod(u: Universe)(asyncMacroSymbol: u.Symbol): u.Symbol = {
import u._
asyncMacroSymbol.owner.typeSignature.member(newTermName("await"))
}
}

protected[async] def nullOut(u: Universe)(name: u.Expr[String], v: u.Expr[Any]): u.Expr[Unit] =
u.reify { () }
}
14 changes: 6 additions & 8 deletions src/main/scala/scala/async/internal/AsyncId.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package scala.async.internal
import language.experimental.macros
import scala.reflect.macros.Context
import scala.reflect.api.Universe
import scala.reflect.internal.SymbolTable

object AsyncId extends AsyncBase {
lazy val futureSystem = IdentityFutureSystem
Expand Down Expand Up @@ -52,12 +51,11 @@ object IdentityFutureSystem extends FutureSystem {
type ExecContext = Unit
type Tryy[A] = scala.util.Try[A]

def mkOps(c: SymbolTable): Ops {val universe: c.type} = new Ops {
val universe: c.type = c
def mkOps(c0: Context): Ops {val c: c0.type} = new Ops {
val c: c0.type = c0
import c.universe._

import universe._

def execContext: Expr[ExecContext] = Expr[Unit](Literal(Constant(())))
def execContext: Expr[ExecContext] = c.Expr[Unit](Literal(Constant(())))

def promType[A: WeakTypeTag]: Type = weakTypeOf[Prom[A]]
def tryType[A: WeakTypeTag]: Type = weakTypeOf[scala.util.Try[A]]
Expand All @@ -76,12 +74,12 @@ object IdentityFutureSystem extends FutureSystem {
def onComplete[A, U](future: Expr[Fut[A]], fun: Expr[Tryy[A] => U],
execContext: Expr[ExecContext]): Expr[Unit] = reify {
fun.splice.apply(util.Success(future.splice))
Expr[Unit](Literal(Constant(()))).splice
c.Expr[Unit](Literal(Constant(()))).splice
}

def completeProm[A](prom: Expr[Prom[A]], value: Expr[Tryy[A]]): Expr[Unit] = reify {
prom.splice.a = value.splice.get
Expr[Unit](Literal(Constant(()))).splice
c.Expr[Unit](Literal(Constant(()))).splice
}

def tryyIsFailure[A](tryy: Expr[Tryy[A]]): Expr[Boolean] = reify {
Expand Down
46 changes: 10 additions & 36 deletions src/main/scala/scala/async/internal/AsyncMacro.scala
Original file line number Diff line number Diff line change
@@ -1,51 +1,25 @@
package scala.async.internal

import scala.tools.nsc.Global
import scala.tools.nsc.transform.TypingTransformers

object AsyncMacro {
def apply(c: reflect.macros.Context, base: AsyncBase): AsyncMacro = {
def apply(c0: reflect.macros.Context, base: AsyncBase): AsyncMacro { val c: c0.type } = {
import language.reflectiveCalls
val powerContext = c.asInstanceOf[c.type { val universe: Global; val callsiteTyper: universe.analyzer.Typer }]
new AsyncMacro {
val global: powerContext.universe.type = powerContext.universe
val callSiteTyper: global.analyzer.Typer = powerContext.callsiteTyper
val macroApplication: global.Tree = c.macroApplication.asInstanceOf[global.Tree]
new AsyncMacro { self =>
val c: c0.type = c0
// This member is required by `AsyncTransform`:
val asyncBase: AsyncBase = base
val asyncBase: AsyncBase = base
// These members are required by `ExprBuilder`:
val futureSystem: FutureSystem = base.futureSystem
val futureSystemOps: futureSystem.Ops {val universe: global.type} = futureSystem.mkOps(global)
val futureSystem: FutureSystem = base.futureSystem
val futureSystemOps: futureSystem.Ops {val c: self.c.type} = futureSystem.mkOps(c)
}
}
}

private[async] trait AsyncMacro
extends TypingTransformers
with AnfTransform with TransformUtils with Lifter
extends AnfTransform with TransformUtils with Lifter
with ExprBuilder with AsyncTransform with AsyncAnalysis with LiveVariables {

val global: Global
val callSiteTyper: global.analyzer.Typer
val macroApplication: global.Tree

lazy val macroPos = macroApplication.pos.makeTransparent
def atMacroPos(t: global.Tree) = global.atPos(macroPos)(t)

def suppressExpansion() {
// Have your cake : Scala IDE sees original trees and hyperlinking, etc within async blocks "Just Works"
// Eat it too : (domain specific errors like "unsupported use of await"
//
// TODO remove this once we unsupport 2.10.x, scalac 2.11 does this automatically.

import global.Tree
type Suppress = { def suppressMacroExpansion(a: Tree): Tree }
try {
global.asInstanceOf[Suppress].suppressMacroExpansion(macroApplication)
} catch {
case _: NoSuchMethodException =>
global.analyzer.asInstanceOf[Suppress].suppressMacroExpansion(macroApplication)
}
}
val c: scala.reflect.macros.Context

lazy val macroPos = c.macroApplication.pos.makeTransparent
def atMacroPos(t: c.Tree) = c.universe.atPos(macroPos)(t)
}
Loading