From 3a148cd0cd404751095cd1c5aca09ad8923c51ab Mon Sep 17 00:00:00 2001 From: Den Shabalin Date: Fri, 20 Sep 2013 13:32:38 +0200 Subject: SI-6841 SI-6657 add support for packages into quasiquotes and toolbox In order to implement this a new parser entry point `parseStatsOrPackages` that augments current parseStats with ability to parse "package name { ... }" syntax. --- .../neg/quasiquotes-syntax-error-position.check | 4 +- test/files/run/toolbox_parse_package.check | 8 ++++ test/files/run/toolbox_parse_package.scala | 9 ++++ .../quasiquotes/DefinitionConstructionProps.scala | 50 ++++++++++++++++++++++ .../DefinitionDeconstructionProps.scala | 24 +++++++++++ 5 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 test/files/run/toolbox_parse_package.check create mode 100644 test/files/run/toolbox_parse_package.scala (limited to 'test') diff --git a/test/files/neg/quasiquotes-syntax-error-position.check b/test/files/neg/quasiquotes-syntax-error-position.check index 3bd813b1bb..25e5b8d75a 100644 --- a/test/files/neg/quasiquotes-syntax-error-position.check +++ b/test/files/neg/quasiquotes-syntax-error-position.check @@ -10,9 +10,9 @@ quasiquotes-syntax-error-position.scala:7: error: '}' expected but end of quote quasiquotes-syntax-error-position.scala:8: error: '.' expected but splicee found. q"import $t $t" ^ -quasiquotes-syntax-error-position.scala:9: error: illegal start of definition +quasiquotes-syntax-error-position.scala:9: error: '{' expected but end of quote found. q"package p" - ^ + ^ quasiquotes-syntax-error-position.scala:10: error: ';' expected but '@' found. q"foo@$a" ^ diff --git a/test/files/run/toolbox_parse_package.check b/test/files/run/toolbox_parse_package.check new file mode 100644 index 0000000000..46465980a0 --- /dev/null +++ b/test/files/run/toolbox_parse_package.check @@ -0,0 +1,8 @@ +package foo { + object bar extends scala.AnyRef { + def () = { + super.(); + () + } + } +} diff --git a/test/files/run/toolbox_parse_package.scala b/test/files/run/toolbox_parse_package.scala new file mode 100644 index 0000000000..62412a50d7 --- /dev/null +++ b/test/files/run/toolbox_parse_package.scala @@ -0,0 +1,9 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{universe => ru} +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val toolbox = cm.mkToolBox() + println(toolbox.parse("package foo { object bar }")) +} \ No newline at end of file diff --git a/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala index ced479aef5..e8ddb4b72a 100644 --- a/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/DefinitionConstructionProps.scala @@ -13,6 +13,7 @@ object DefinitionConstructionProps with TraitConstruction with TypeDefConstruction with ValDefConstruction + with PackageConstruction trait ClassConstruction { self: QuasiquoteProperties => val anyRef = ScalaDot(TypeName("AnyRef")) @@ -292,4 +293,53 @@ trait MethodConstruction { self: QuasiquoteProperties => val a = q"new Foo(a)(b)" assertEqAst(q"@$a def foo", "@Foo(a)(b) def foo") } +} + +trait PackageConstruction { self: QuasiquoteProperties => + property("splice select into package name") = test { + val name = q"foo.bar" + assertEqAst(q"package $name { }", "package foo.bar { }") + } + + property("splce name into package name") = test{ + val name = TermName("bippy") + assertEqAst(q"package $name { }", "package bippy { }") + } + + property("splice members into package body") = test { + val members = q"class C" :: q"object O" :: Nil + assertEqAst(q"package foo { ..$members }", "package foo { class C; object O }") + } + + property("splice illegal members into package body") = test { + val f = q"def f" + assertThrows[IllegalArgumentException] { q"package foo { $f }" } + val v = q"val v = 0" + assertThrows[IllegalArgumentException] { q"package foo { $v }" } + val expr = q"x + 1" + assertThrows[IllegalArgumentException] { q"package foo { $expr }" } + } + + property("splice name into package object") = test { + val foo = TermName("foo") + assertEqAst(q"package object $foo", "package object foo") + } + + property("splice parents into package object") = test { + val parents = tq"a" :: tq"b" :: Nil + assertEqAst(q"package object foo extends ..$parents", + "package object foo extends a with b") + } + + property("splice members into package object") = test { + val members = q"def foo" :: q"val x = 1" :: Nil + assertEqAst(q"package object foo { ..$members }", + "package object foo { def foo; val x = 1 }") + } + + property("splice early def into package object") = test { + val edefs = q"val x = 1" :: q"type I = Int" :: Nil + assertEqAst(q"package object foo extends { ..$edefs } with Any", + "package object foo extends { val x = 1; type I = Int } with Any") + } } \ No newline at end of file diff --git a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala index fdfbfe871c..993ef899b0 100644 --- a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala @@ -13,6 +13,7 @@ object DefinitionDeconstructionProps with ObjectDeconstruction with ModsDeconstruction with ValVarDeconstruction + with PackageDeconstruction trait TraitDeconstruction { self: QuasiquoteProperties => property("exhaustive trait matcher") = test { @@ -144,4 +145,27 @@ trait ValVarDeconstruction { self: QuasiquoteProperties => matches("var x = 1") assertThrows[MatchError] { matches("val x = 1") } } +} + +trait PackageDeconstruction { self: QuasiquoteProperties => + property("exhaustive package matcher") = test { + def matches(line: String) { val q"package $name { ..$body }" = parse(line) } + matches("package foo { }") + matches("package foo { class C }") + matches("package foo.bar { }") + matches("package bippy.bongo { object A; object B }") + matches("package bippy { package bongo { object O } }") + } + + property("exhaustive package object matcher") = test { + def matches(line: String) { + val q"package object $name extends { ..$early } with ..$parents { $self => ..$body }" = parse(line) + } + matches("package object foo") + matches("package object foo { def baz }") + matches("package object foo { self => }") + matches("package object foo extends mammy with daddy { def baz }") + matches("package object foo extends { val early = 1 } with daddy") + assertThrows[MatchError] { matches("object foo") } + } } \ No newline at end of file -- cgit v1.2.3