mirror of https://github.com/sbt/sbt.git
support explicit types on lazy vals in definingValName
lazy val x: Project = project has a rather different enclosing tree than lazy val x = project.
This commit is contained in:
parent
54b103f4c7
commit
1fdf3fa38c
|
|
@ -31,15 +31,20 @@ private[sbt] object KeyMacro
|
||||||
def definingValName(c: Context, invalidEnclosingTree: String => String): String =
|
def definingValName(c: Context, invalidEnclosingTree: String => String): String =
|
||||||
{
|
{
|
||||||
import c.universe.{Apply=>ApplyTree,_}
|
import c.universe.{Apply=>ApplyTree,_}
|
||||||
val methodName = c.macroApplication.symbol.name.decoded
|
val methodName = c.macroApplication.symbol.name
|
||||||
|
def processName(n: Name): String = n.decoded.trim // trim is not strictly correct, but macros don't expose the API necessary
|
||||||
def enclosingVal(trees: List[c.Tree]): String =
|
def enclosingVal(trees: List[c.Tree]): String =
|
||||||
|
{
|
||||||
trees match {
|
trees match {
|
||||||
case vd @ ValDef(_, name, _, _) :: ts => name.decoded
|
case vd @ ValDef(_, name, _, _) :: ts => processName(name)
|
||||||
case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs)
|
case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs)
|
||||||
|
// lazy val x: X = <methodName> has this form for some reason (only when the explicit type is present, though)
|
||||||
|
case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => processName(name)
|
||||||
case _ =>
|
case _ =>
|
||||||
c.error(c.enclosingPosition, invalidEnclosingTree(methodName))
|
c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decoded))
|
||||||
"<error>"
|
"<error>"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
enclosingVal(enclosingTrees(c).toList)
|
enclosingVal(enclosingTrees(c).toList)
|
||||||
}
|
}
|
||||||
def enclosingTrees(c: Context): Seq[c.Tree] =
|
def enclosingTrees(c: Context): Seq[c.Tree] =
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import org.scalacheck._
|
||||||
|
import Prop._
|
||||||
|
import Project.project
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class ProjectDefs
|
||||||
|
{
|
||||||
|
lazy val p = project
|
||||||
|
|
||||||
|
val x = project
|
||||||
|
|
||||||
|
// should not compile
|
||||||
|
// def y = project
|
||||||
|
|
||||||
|
val z = project in new File("dir")
|
||||||
|
|
||||||
|
val a: Project = project
|
||||||
|
|
||||||
|
lazy val aa: Project = project
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object ProjectMacro extends Properties("ProjectMacro")
|
||||||
|
{
|
||||||
|
lazy val pd = new ProjectDefs
|
||||||
|
import pd._
|
||||||
|
|
||||||
|
def secure(f: => Prop): Prop = try {
|
||||||
|
Prop.secure(f)
|
||||||
|
} catch { case e: Throwable =>
|
||||||
|
e.printStackTrace
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
|
||||||
|
property("Explicit type on lazy val supported") = secure {
|
||||||
|
check(aa, "aa", "aa")
|
||||||
|
}
|
||||||
|
|
||||||
|
property("Explicit type on val supported") = secure {
|
||||||
|
check(a, "a", "a")
|
||||||
|
}
|
||||||
|
|
||||||
|
property("lazy vals supported") = secure {
|
||||||
|
check(p, "p", "p")
|
||||||
|
}
|
||||||
|
|
||||||
|
property("plain vals supported") = secure {
|
||||||
|
check(x, "x", "x")
|
||||||
|
}
|
||||||
|
|
||||||
|
property("Directory overridable") = secure {
|
||||||
|
check(z, "z", "dir")
|
||||||
|
}
|
||||||
|
|
||||||
|
def check(p: Project, id: String, dir: String): Prop =
|
||||||
|
{
|
||||||
|
s"Expected id: $id" |:
|
||||||
|
s"Expected dir: $dir" |:
|
||||||
|
s"Actual id: ${p.id}" |:
|
||||||
|
s"Actual dir: ${p.base}" |:
|
||||||
|
(p.id == id) &&
|
||||||
|
(p.base.getName == dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue