diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-10-04 07:37:41 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-10-11 19:53:52 +0200 |
commit | 6eb48f9602c3a21c85a38651c2e0b887e06b8d18 (patch) | |
tree | 641403b5a61dcc12d3419c0028a786ffc21cafff /src/reflect/scala/reflect/api/Constants.scala | |
parent | 553ee0118dbc052bed8c4580376b48cd9cb5d0f9 (diff) | |
download | scala-6eb48f9602c3a21c85a38651c2e0b887e06b8d18.tar.gz scala-6eb48f9602c3a21c85a38651c2e0b887e06b8d18.tar.bz2 scala-6eb48f9602c3a21c85a38651c2e0b887e06b8d18.zip |
docs for reflection and macros
Diffstat (limited to 'src/reflect/scala/reflect/api/Constants.scala')
-rw-r--r-- | src/reflect/scala/reflect/api/Constants.scala | 84 |
1 files changed, 81 insertions, 3 deletions
diff --git a/src/reflect/scala/reflect/api/Constants.scala b/src/reflect/scala/reflect/api/Constants.scala index 2f201d033d..1f303877de 100644 --- a/src/reflect/scala/reflect/api/Constants.scala +++ b/src/reflect/scala/reflect/api/Constants.scala @@ -6,10 +6,82 @@ package scala.reflect package api -/** - * Defines the type hierachy for compile-time constants. +/** A slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines compile-time constants and operations on them. + * See [[scala.reflect.api.Universe]] for a description of how the reflection API is encoded with the cake pattern. * - * @see [[scala.reflect]] for a description on how the class hierarchy is encoded here. + * According to the section 6.24 "Constant Expressions" of the Scala language specification, + * certain expressions (dubbed ''constant expressions'') can be evaluated by the Scala compiler at compile-time. + * + * [[scala.reflect.api.Constants#Constant]] instances represent certain kinds of these expressions + * (with values stored in the `value` field and its strongly-typed views named `booleanValue`, `intValue` etc.), namely: + * 1. Literals of primitive value classes (bytes, shorts, ints, longs, floats, doubles, chars, booleans and voids). + * 1. String literals. + * 1. References to classes (typically constructed with [[scala.Predef#classOf]]). + * 1. References to enumeration values. + * + * Such constants are used to represent literals in abstract syntax trees (the [[scala.reflect.api.Trees#Literal]] node) + * and literal arguments for Java class file annotations (the [[scala.reflect.api.Annotations#LiteralArgument]] class). + * + * === Example === + * + * The `value` field deserves some explanation. Primitive and string values are represented as themselves, whereas + * references to classes and enums are a bit roundabout. + * + * Class references are represented as instances of [[scala.reflect.api.Types#Type]] + * (because when the Scala compiler processes a class reference, the underlying runtime class might not yet have been compiled). + * To convert such a reference to a runtime class, one should use the `runtimeClass` method of a mirror such as [[scala.reflect.api.Mirrors#RuntimeMirror]] + * (the simplest way to get such a mirror is using [[scala.reflect.runtime.package#currentMirror]]). + * + * Enumeration value references are represented as instances of [[scala.reflect.api.Symbols#Symbol]], which on JVM point to methods + * that return underlying enum values. To inspect an underlying enumeration or to get runtime value of a reference to an enum, + * one should use a [[scala.reflect.api.Mirrors#RuntimeMirror]] (the simplest way to get such a mirror is again [[scala.reflect.runtime.package#currentMirror]]). + + * {{{ + * enum JavaSimpleEnumeration { FOO, BAR } + * + * import java.lang.annotation.*; + * @Retention(RetentionPolicy.RUNTIME) + * @Target({ElementType.TYPE}) + * public @interface JavaSimpleAnnotation { + * Class<?> classRef(); + * JavaSimpleEnumeration enumRef(); + * } + * + * @JavaSimpleAnnotation( + * classRef = JavaAnnottee.class, + * enumRef = JavaSimpleEnumeration.BAR + * ) + * public class JavaAnnottee {} + * }}} + * {{{ + * import scala.reflect.runtime.universe._ + * import scala.reflect.runtime.{currentMirror => cm} + * + * object Test extends App { + * val jann = typeOf[JavaAnnottee].typeSymbol.annotations(0).javaArgs + * def jarg(name: String) = jann(newTermName(name)).asInstanceOf[LiteralArgument].value + * + * val classRef = jarg("classRef").typeValue + * println(showRaw(classRef)) // TypeRef(ThisType(<empty>), JavaAnnottee, List()) + * println(cm.runtimeClass(classRef)) // class JavaAnnottee + * + * val enumRef = jarg("enumRef").symbolValue + * println(enumRef) // value BAR + * + * val siblings = enumRef.owner.typeSignature.declarations + * val enumValues = siblings.filter(sym => sym.isVal && sym.isPublic) + * println(enumValues) // Scope{ + * // final val FOO: JavaSimpleEnumeration; + * // final val BAR: JavaSimpleEnumeration + * // } + * + * // doesn't work because of https://issues.scala-lang.org/browse/SI-6459 + * // val enumValue = mirror.reflectField(enumRef.asTerm).get + * val enumClass = cm.runtimeClass(enumRef.owner.asClass) + * val enumValue = enumClass.getDeclaredField(enumRef.name.toString).get(null) + * println(enumValue) // BAR + * } + * }}} */ trait Constants { self: Universe => @@ -34,8 +106,14 @@ trait Constants { def unapply(arg: Constant): Option[Any] } + /** The API of `Constant` instances. + * The main source of information about constants is the [[scala.reflect.api.Constants]] page. + */ abstract class ConstantApi { + /** Payload of the constant. */ val value: Any + + /** Scala type that describes the constant. */ def tpe: Type } } |