summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-08-10 14:51:34 +0200
committerEugene Burmako <xeno.by@gmail.com>2013-08-14 22:04:43 +0200
commit1b5f73129fc2f678d00905e5d851536251f8821a (patch)
treeb512c8ac4576f91b0420d7f55d8da643dfcc60c3
parent4c62f7db6f3913eedd92d85daf8f631149cc97b2 (diff)
downloadscala-1b5f73129fc2f678d00905e5d851536251f8821a.tar.gz
scala-1b5f73129fc2f678d00905e5d851536251f8821a.tar.bz2
scala-1b5f73129fc2f678d00905e5d851536251f8821a.zip
moves compileTimeOnly to scala-library
This is the notion that's come to be universally useful, so I suggest we promote it to be universally accessible. Note that the attached test incorrectly fails to report errors for definitions coming from the empty package and for annotations. These are bugs, and they are fixed in subsequent commits of this pull request.
-rw-r--r--src/library/scala/annotation/compileTimeOnly.scala22
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/annotations/compileTimeOnly.scala32
-rw-r--r--src/reflect/scala/reflect/internal/annotations/package.scala6
-rw-r--r--test/files/neg/compile-time-only-a.check19
-rw-r--r--test/files/neg/compile-time-only-a.scala57
6 files changed, 105 insertions, 33 deletions
diff --git a/src/library/scala/annotation/compileTimeOnly.scala b/src/library/scala/annotation/compileTimeOnly.scala
new file mode 100644
index 0000000000..942e9cad8c
--- /dev/null
+++ b/src/library/scala/annotation/compileTimeOnly.scala
@@ -0,0 +1,22 @@
+package scala.annotation
+
+import scala.annotation.meta._
+
+/**
+ * An annotation that designates that an annottee should not be referred to after
+ * type checking (which includes macro expansion).
+ *
+ * Examples of potential use:
+ * 1) The annottee can only appear in the arguments of some other macro
+ * that will eliminate it from the AST during expansion.
+ * 2) The annottee is a macro and should have been expanded away,
+ * so if hasn't, something wrong has happened.
+ * (Comes in handy to provide better support for new macro flavors,
+ * e.g. macro annotations, that can't be expanded by the vanilla compiler).
+ *
+ * @param message the error message to print during compilation if a reference remains
+ * after type checking
+ * @since 2.11.0
+ */
+@getter @setter @beanGetter @beanSetter @companionClass @companionMethod
+final class compileTimeOnly(message: String) extends scala.annotation.StaticAnnotation
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 6b7aa2dddf..d70ba366c4 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -904,7 +904,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty]
lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty]
- lazy val CompileTimeOnlyAttr = getClassIfDefined("scala.reflect.internal.annotations.compileTimeOnly")
+ lazy val CompileTimeOnlyAttr = getClassIfDefined("scala.annotation.compileTimeOnly")
lazy val DeprecatedAttr = requiredClass[scala.deprecated]
lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName]
lazy val DeprecatedInheritanceAttr = requiredClass[scala.deprecatedInheritance]
diff --git a/src/reflect/scala/reflect/internal/annotations/compileTimeOnly.scala b/src/reflect/scala/reflect/internal/annotations/compileTimeOnly.scala
deleted file mode 100644
index 2c9f909629..0000000000
--- a/src/reflect/scala/reflect/internal/annotations/compileTimeOnly.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-package scala
-package reflect
-package internal
-package annotations
-
-import scala.annotation.meta._
-
-/**
- * An annotation that designates a member should not be referred to after
- * type checking (which includes macro expansion); it must only be used in
- * the arguments of some other macro that will eliminate it from the AST.
- *
- * Later on, this annotation should be removed and implemented with domain-specific macros.
- * If a certain method `inner` mustn't be called outside the context of a given macro `outer`,
- * then it should itself be declared as a macro.
- *
- * Approach #1. Expansion of `inner` checks whether its enclosures contain `outer` and
- * report an error if `outer` is not detected. In principle, we could use this approach right now,
- * but currently enclosures are broken, because contexts aren't exactly famous for keeping precise
- * track of the stack of the trees being typechecked.
- *
- * Approach #2. Default implementation of `inner` is just an invocation of `c.abort`.
- * `outer` is an untyped macro, which expands into a block, which contains a redefinition of `inner`
- * and a call to itself. The redefined `inner` could either be a stub like `Expr.splice` or carry out
- * domain-specific logic.
- *
- * @param message the error message to print during compilation if a reference remains
- * after type checking
- * @since 2.10.1
- */
-@getter @setter @beanGetter @beanSetter
-final class compileTimeOnly(message: String) extends scala.annotation.StaticAnnotation
diff --git a/src/reflect/scala/reflect/internal/annotations/package.scala b/src/reflect/scala/reflect/internal/annotations/package.scala
new file mode 100644
index 0000000000..ef299a600c
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/annotations/package.scala
@@ -0,0 +1,6 @@
+package scala.reflect.internal
+
+package object annotations {
+ @deprecated("Use scala.annotation.compileTimeOnly instead", "2.11.0")
+ type compileTimeOnly = scala.annotation.compileTimeOnly
+} \ No newline at end of file
diff --git a/test/files/neg/compile-time-only-a.check b/test/files/neg/compile-time-only-a.check
new file mode 100644
index 0000000000..99d7a8e2dd
--- /dev/null
+++ b/test/files/neg/compile-time-only-a.check
@@ -0,0 +1,19 @@
+compile-time-only-a.scala:41: error: C5
+ 2.ext
+ ^
+compile-time-only-a.scala:42: error: C5
+ C5(2)
+ ^
+compile-time-only-a.scala:45: error: C6.x
+ val _ = c6.x
+ ^
+compile-time-only-a.scala:46: error: C6.foo
+ c6.foo
+ ^
+compile-time-only-a.scala:48: error: C6.y
+ c6.y = c6.y
+ ^
+compile-time-only-a.scala:48: error: C6.y
+ c6.y = c6.y
+ ^
+6 errors found
diff --git a/test/files/neg/compile-time-only-a.scala b/test/files/neg/compile-time-only-a.scala
new file mode 100644
index 0000000000..43d36dfab1
--- /dev/null
+++ b/test/files/neg/compile-time-only-a.scala
@@ -0,0 +1,57 @@
+import scala.annotation.compileTimeOnly
+
+@compileTimeOnly("C1") class C1
+object C1
+
+class C2
+@compileTimeOnly("C2") object C2
+
+@compileTimeOnly("C3") case class C3(x: Int)
+
+@compileTimeOnly("C4") case class C4(x: Int)
+object C4
+
+object pkg {
+ @compileTimeOnly("C5")
+ implicit class C5(val x: Int) {
+ def ext = ???
+ }
+}
+
+class C6(@compileTimeOnly("C6.x") val x: Int) {
+ @compileTimeOnly("C6.foo") def foo = 2
+ @compileTimeOnly("C6.Foo") type Foo = Int
+ @compileTimeOnly("C6.y") var y = 3
+}
+
+object Test extends App {
+ new C1()
+ C1
+
+ new C2()
+ C2
+
+ new C3(2)
+ C3(2)
+
+ new C4(2)
+ C4(2)
+
+ import pkg._
+ 2.ext
+ C5(2)
+
+ val c6 = new C6(2)
+ val _ = c6.x
+ c6.foo
+ type Foo = c6.Foo
+ c6.y = c6.y
+}
+
+@compileTimeOnly("placebo")
+class placebo extends scala.annotation.StaticAnnotation
+
+@placebo
+class Test {
+ @placebo def x = (2: @placebo)
+} \ No newline at end of file