Skip to content

Commit ecbb25a

Browse files
committed
improved/fixed reflection docs based on comments
1 parent bbd2e43 commit ecbb25a

15 files changed

+155
-70
lines changed

src/library/scala/reflect/ClassTag.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass }
99
*
1010
* If an implicit value of type ClassTag[T] is requested, the compiler will create one.
1111
* The runtime class (i.e. the erasure, a java.lang.Class on the JVM) of T can be accessed
12-
* via the `runtimeClass` field. References to type parameters or abstract types are
12+
* via the `runtimeClass` field. References to type parameters or abstract type members are
1313
* replaced by the concrete types if ClassTags are available for them.
1414
*
15-
* Besides accessing the erasure, a ClassTag knows how instantiate single- and multi-
15+
* Besides accessing the erasure, a ClassTag knows how to instantiate single- and multi-
1616
* dimensional `Arrays` where the element type is unknown at compile time.
1717
*
1818
* [[scala.reflect.ClassTag]] corresponds to a previous concept of [[scala.reflect.ClassManifest]].

src/library/scala/reflect/base/Annotations.scala

+10-11
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ trait Annotations { self: Universe =>
1010

1111
/** Typed information about an annotation. It can be attached to either a symbol or an annotated type.
1212
*
13-
* Annotations are either ''Scala annotations'', which conform to [[scala.annotation.Annotation]] or [[scala.annotation.StaticAnnotation]]
14-
* but not [[scala.annotation.ClassfileAnnotation]] or ''Java annotations'', which conform to [[scala.annotation.ClassfileAnnotation]].
13+
* Annotations are either ''Scala annotations'', which conform to [[scala.annotation.StaticAnnotation]]
14+
* or ''Java annotations'', which conform to [[scala.annotation.ClassfileAnnotation]].
1515
* Trait `ClassfileAnnotation` is automatically added to every Java annotation by the scalac classfile parser.
1616
*/
1717
type Annotation >: Null <: AnyRef
@@ -24,17 +24,16 @@ trait Annotations { self: Universe =>
2424
/** The constructor/deconstructor for `Annotation` instances. */
2525
val Annotation: AnnotationExtractor
2626

27-
/** An extractor class to create and pattern match with syntax `Annotation(atp, args, javaArgs)`.
28-
* Here, `atp` is the annotation type, `args` the arguments, and `javaArgs` the annotation's key-value
27+
/** An extractor class to create and pattern match with syntax `Annotation(atp, scalaArgs, javaArgs)`.
28+
* Here, `atp` is the annotation type, `scalaArgs` the arguments, and `javaArgs` the annotation's key-value
2929
* pairs.
3030
*
31-
* Annotations are written to the classfile as Java annotations if `atp` conforms to
32-
* `ClassfileAnnotation`. Annotations are pickled, i.e., written to scala symtab attribute in the classfile,
33-
* if `atp` inherits from `StaticAnnotation` but not `ClassfileAnnotation`.
31+
* Annotations are pickled, i.e. written to scala symtab attribute in the classfile.
32+
* Annotations are written to the classfile as Java annotations if `atp` conforms to `ClassfileAnnotation`.
3433
*
35-
* For Scala annotations, arguments are stored in `args` and `javaArgs` is empty. Arguments in
36-
* `args` are represented as typed trees. Note that these trees are not transformed by any phases
37-
* following the type-checker. For Java annotations, `args` is empty and arguments are stored in
34+
* For Scala annotations, arguments are stored in `scalaArgs` and `javaArgs` is empty. Arguments in
35+
* `scalaArgs` are represented as typed trees. Note that these trees are not transformed by any phases
36+
* following the type-checker. For Java annotations, `scalaArgs` is empty and arguments are stored in
3837
* `javaArgs`.
3938
*/
4039
abstract class AnnotationExtractor {
@@ -85,7 +84,7 @@ trait Annotations { self: Universe =>
8584
def unapply(arg: ArrayArgument): Option[Array[JavaArgument]]
8685
}
8786

88-
/** A nested argument to a Java annotation as `@Nested` in `@Outer(@Nested)`.
87+
/** A nested annotation argument to a Java annotation as `@Nested` in `@Outer(@Nested)`.
8988
*/
9089
type NestedArgument >: Null <: AnyRef with JavaArgument
9190

src/library/scala/reflect/base/Attachments.scala

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package scala.reflect
22
package base
33

4-
/** Attachments is a generalisation of Position. Typically it stores a Position of a tree, but this can be extended to
5-
* encompass arbitrary payloads.
4+
/** Attachments is a generalization of Position. Typically it stores a Position of a tree, but this can be extended to
5+
* encompass arbitrary payloads. Payloads are stored in type-indexed slots, which can be read with `get[T]` and written
6+
* with `update[T]` and `remove[T]`.
67
*
78
* Attachments always carry positions because we don't want to introduce an additional field for attachments in `Tree`
89
* imposing an unnecessary memory tax because of something that will not be used in most cases.
@@ -18,7 +19,7 @@ abstract class Attachments { self =>
1819
/** Creates a copy of this attachment with the position replaced by `newPos` */
1920
def withPos(newPos: Pos): Attachments { type Pos = self.Pos }
2021

21-
/** The underlying payload. */
22+
/** The underlying payload with the guarantee that no two elements have the same type. */
2223
def all: Set[Any] = Set.empty
2324

2425
private def matchesTag[T: ClassTag](datum: Any) =
@@ -28,11 +29,14 @@ abstract class Attachments { self =>
2829
def get[T: ClassTag]: Option[T] =
2930
(all filter matchesTag[T]).headOption.asInstanceOf[Option[T]]
3031

31-
/** Creates a copy of this attachment with a new payload added */
32+
/** Creates a copy of this attachment with the payload slot of T added/updated with the provided value.
33+
*
34+
* Replaces an existing payload of the same type, if exists.
35+
*/
3236
def update[T: ClassTag](attachment: T): Attachments { type Pos = self.Pos } =
3337
new NonemptyAttachments(this.pos, remove[T].all + attachment)
3438

35-
/** Creates a copy of this attachment with all payloads of the given class type `T` removed. */
39+
/** Creates a copy of this attachment with the payload of the given class type `T` removed. */
3640
def remove[T: ClassTag]: Attachments { type Pos = self.Pos } = {
3741
val newAll = all filterNot matchesTag[T]
3842
if (newAll.isEmpty) pos.asInstanceOf[Attachments { type Pos = self.Pos }]

src/library/scala/reflect/base/Exprs.scala

+20-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ trait Exprs { self: Universe =>
1212
trait Expr[+T] extends Equals with Serializable {
1313
val mirror: Mirror
1414
/**
15-
* Migrates the expression into another universe given its corresponding mirror.
15+
* Migrates the expression into another mirror, jumping into a different universe if necessary.
16+
*
17+
* This means that all symbolic references to classes/objects/packages in the expression
18+
* will be re-resolved within the new mirror (typically using that mirror's classloader).
1619
*/
1720
def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T]
1821

@@ -32,6 +35,7 @@ trait Exprs { self: Universe =>
3235

3336
/**
3437
* A dummy method to mark expression splicing in reification.
38+
*
3539
* It should only be used within a `reify` call, which eliminates the `splice` call and embeds
3640
* the wrapped tree into the reified surrounding expression.
3741
* If used alone `splice` throws an exception when called at runtime.
@@ -52,10 +56,23 @@ trait Exprs { self: Universe =>
5256
* {{{
5357
* reify{ expr.foo }
5458
* }}}
55-
* because expr of type Expr[T] does not have a method foo.
59+
* because expr of type Expr[T] itself does not have a method foo.
5660
*/
5761
def splice: T
58-
// TODO: document this
62+
/**
63+
* A dummy value to denote cross-stage path-dependent type dependencies.
64+
*
65+
* For example for the following macro definition:
66+
* {{{
67+
* class X { type T }
68+
* object Macros { def foo(x: X): x.T = macro Impls.foo_impl }
69+
* }}}
70+
*
71+
* The corresponding macro implementation should have the following signature (note how the return type denotes path-dependency on x):
72+
* {{{
73+
* object Impls { def foo_impl(c: Context)(x: c.Expr[X]): c.Expr[x.value.T] = ... }
74+
* }}}
75+
*/
5976
val value: T
6077

6178
/** case class accessories */

src/library/scala/reflect/base/MirrorOf.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ abstract class MirrorOf[U <: base.Universe with Singleton] {
2424
/** The module symbol of the `_root_` package */
2525
def RootPackage: U#ModuleSymbol
2626

27-
/** The class symbol of the default (unnamed) package */
27+
/** The module class symbol of the default (unnamed) package */
2828
def EmptyPackageClass: U#ClassSymbol
2929

3030
/** The module symbol of the default (unnamed) package */

src/library/scala/reflect/base/Mirrors.scala

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ trait Mirrors {
1515
/** The base type of all mirrors of this universe */
1616
type Mirror >: Null <: MirrorOf[self.type]
1717

18-
/** The roor mirror of this universe. This mirror contains standard Scala classes and types such as `Any`, `AnyRef`, `AnyVal`,
19-
* `Nothing`, `Null`, and all classes loaded from scala-library. The root package of this mirror contains the root
20-
* packages of all other mirrors of this universe as members.
18+
/** The root mirror of this universe. This mirror contains standard Scala classes and types such as `Any`, `AnyRef`, `AnyVal`,
19+
* `Nothing`, `Null`, and all classes loaded from scala-library, which are shared across all mirrors within the enclosing universe.
2120
*/
2221
val rootMirror: Mirror
2322
}

src/library/scala/reflect/base/Names.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ trait Names {
3737

3838
/** The base API that all names support */
3939
abstract class NameBase {
40-
/** Checks weather the name is a a term name */
40+
/** Checks wether the name is a a term name */
4141
def isTermName: Boolean
4242

43-
/** Checks weather the name is a a type name */
43+
/** Checks wether the name is a a type name */
4444
def isTypeName: Boolean
4545

4646
/** Returns a term name that wraps the same string as `this` */
@@ -58,11 +58,11 @@ trait Names {
5858
*/
5959
def newTypeName(s: String): TypeName
6060

61-
/** Wraps the empty string
61+
/** Wraps the empty string. Can be used as the null object for term name.
6262
*/
6363
def EmptyTermName: TermName = newTermName("")
6464

65-
/** Wraps the empty string
65+
/** Wraps the empty string. Can be used as the null object for term name.
6666
*/
6767
def EmptyTypeName: TypeName = EmptyTermName.toTypeName
6868
}

src/library/scala/reflect/base/StandardDefinitions.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ trait StandardDefinitions {
2020
/** The class symbol of package `scala`. */
2121
def ScalaPackageClass: ClassSymbol
2222

23-
/** The module symbol of package `scala`. */
23+
/** The module class symbol of package `scala`. */
2424
def ScalaPackage: ModuleSymbol
2525

2626
// top types

src/library/scala/reflect/base/Symbols.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ trait Symbols { self: Universe =>
8686
* that directly contains the current symbol's definition.
8787
* The `NoSymbol` symbol does not have an owner, and calling this method
8888
* on one causes an internal error.
89-
* The owner of the Scala root class [[scala.reflect.api.mirror.RootClass]]
90-
* and the Scala root object [[scala.reflect.api.mirror.RootPackage]] is `NoSymbol`.
89+
* The owner of the Scala root class [[scala.reflect.base.MirrorOf.RootClass]]
90+
* and the Scala root object [[scala.reflect.base.MirrorOf.RootPackage]] is `NoSymbol`.
9191
* Every other symbol has a chain of owners that ends in
92-
* [[scala.reflect.api.mirror.RootClass]].
92+
* [[scala.reflect.base.MirrorOf.RootClass]].
9393
*/
9494
def owner: Symbol
9595

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
package scala.reflect
22
package base
33

4+
/** A mirror-aware factory for trees.
5+
*
6+
* In the reflection API, artifacts are specific to universes and
7+
* symbolic references used in artifacts (e.g. `scala.Int`) are resolved by mirrors.
8+
*
9+
* Therefore to build a tree one needs to know a universe that the tree is going to be bound to
10+
* and a mirror that is going to resolve symbolic references (e.g. to determine that `scala.Int`
11+
* points to a core class `Int` from scala-library.jar).
12+
*
13+
* `TreeCreator` implements this notion by providing a standalone tree factory.
14+
*
15+
* This is immediately useful for reification. When the compiler reifies an expression,
16+
* the end result needs to make sense in any mirror. That's because the compiler knows
17+
* the universe it's reifying an expression into (specified by the target of the `reify` call),
18+
* but it cannot know in advance the mirror to instantiate the result in (e.g. on JVM
19+
* it doesn't know what classloader use to resolve symbolic names in the reifee).
20+
*
21+
* Due to a typechecker restriction (no eta-expansion for dependent method types),
22+
* `TreeCreator` can't have a functional type, so it's implemented as class with an apply method.
23+
*/
424
abstract class TreeCreator {
525
def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Tree
626
}

src/library/scala/reflect/base/Trees.scala

+18-16
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ trait Trees { self: Universe =>
8888
/** The empty tree */
8989
val EmptyTree: Tree
9090

91-
/** A tree for a term. Not all trees are TermTrees; use isTerm
91+
/** A tree for a term. Not all trees representing terms are TermTrees; use isTerm
9292
* to reliably identify terms.
9393
*/
9494
type TermTree >: Null <: AnyRef with Tree
@@ -98,7 +98,7 @@ trait Trees { self: Universe =>
9898
*/
9999
implicit val TermTreeTag: ClassTag[TermTree]
100100

101-
/** A tree for a type. Not all trees are TypTrees; use isType
101+
/** A tree for a type. Not all trees representing types are TypTrees; use isType
102102
* to reliably identify types.
103103
*/
104104
type TypTree >: Null <: AnyRef with Tree
@@ -250,7 +250,6 @@ trait Trees { self: Universe =>
250250
*/
251251
implicit val ValOrDefDefTag: ClassTag[ValOrDefDef]
252252

253-
// FIXME: document how ValDef in self-types can be recognized. (Only private modifier is set there.)
254253
/** Broadly speaking, a value definition. All these are encoded as ValDefs:
255254
*
256255
* - immutable values, e.g. "val x"
@@ -513,7 +512,7 @@ trait Trees { self: Universe =>
513512

514513
/** Case clause in a pattern match.
515514
* (except for occurrences in switch statements).
516-
* Eliminated by compiler phases patmat/explicitouter.
515+
* Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher)
517516
*/
518517
type CaseDef >: Null <: AnyRef with Tree
519518

@@ -538,7 +537,10 @@ trait Trees { self: Universe =>
538537
def unapply(caseDef: CaseDef): Option[(Tree, Tree, Tree)]
539538
}
540539

541-
/** Alternatives of patterns, eliminated by compiler phases patmat/explicitouter, except for
540+
/** Alternatives of patterns.
541+
*
542+
* Eliminated by compiler phases Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher),
543+
* except for
542544
* occurrences in encoded Switch stmt (i.e. remaining Match(CaseDef(...)))
543545
*/
544546
type Alternative >: Null <: TermTree
@@ -562,7 +564,8 @@ trait Trees { self: Universe =>
562564
}
563565

564566
/** Repetition of pattern.
565-
* Eliminated by compiler phase patmat/explicitouter.
567+
*
568+
* Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher).
566569
*/
567570
type Star >: Null <: TermTree
568571

@@ -585,7 +588,8 @@ trait Trees { self: Universe =>
585588
}
586589

587590
/** Bind a variable to a rhs pattern.
588-
* Eliminated by compiler phase patmat/explicitouter.
591+
*
592+
* Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher).
589593
*
590594
* @param name
591595
* @param body
@@ -610,12 +614,9 @@ trait Trees { self: Universe =>
610614
def unapply(bind: Bind): Option[(Name, Tree)]
611615
}
612616

613-
// TODO: evaluate if UnApply can be removed or at least moved out of reflection.
614617
/**
615618
* Used to represent `unapply` methods in pattern matching.
616619
*
617-
* Introduced by typer, eliminated by patmat/explicitouter.
618-
*
619620
* For example:
620621
* {{{
621622
* 2 match { case Foo(x) => x }
@@ -637,6 +638,8 @@ trait Trees { self: Universe =>
637638
* EmptyTree,
638639
* Ident(newTermName("x")))))
639640
* }}}
641+
*
642+
* Introduced by typer. Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher).
640643
*/
641644
type UnApply >: Null <: TermTree
642645

@@ -705,7 +708,7 @@ trait Trees { self: Universe =>
705708
*
706709
* vparams => body
707710
*
708-
* The symbol of a Function is a synthetic TermSymbol having its name set to nme.ANON_FUN_NAME.
711+
* The symbol of a Function is a synthetic TermSymbol.
709712
* It is the owner of the function's parameters.
710713
*/
711714
abstract class FunctionExtractor {
@@ -786,10 +789,10 @@ trait Trees { self: Universe =>
786789
def unapply(if_ : If): Option[(Tree, Tree, Tree)]
787790
}
788791

789-
/** - Pattern matching expression (before compiler phase explicitouter)
790-
* - Switch statements (after compiler phase explicitouter)
792+
/** - Pattern matching expression (before compiler phase explicitouter before 2.10 / patmat from 2.10)
793+
* - Switch statements (after compiler phase explicitouter before 2.10 / patmat from 2.10)
791794
*
792-
* After compiler phase explicitouter, cases will satisfy the following constraints:
795+
* After compiler phase explicitouter before 2.10 / patmat from 2.10, cases will satisfy the following constraints:
793796
*
794797
* - all guards are `EmptyTree`,
795798
* - all patterns will be either `Literal(Constant(x:Int))`
@@ -1002,9 +1005,8 @@ trait Trees { self: Universe =>
10021005
def unapply(apply: Apply): Option[(Tree, List[Tree])]
10031006
}
10041007

1005-
// TODO: what is it used for exactly? extend docs!
10061008
/** Super reference, where `qual` is the corresponding `this` reference.
1007-
* A super reference C.super[M] is represented as Super(This(C), M).
1009+
* A super reference `C.super[M]` is represented as `Super(This(C), M)`.
10081010
*/
10091011
type Super >: Null <: TermTree
10101012

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
package scala.reflect
22
package base
33

4+
/** A mirror-aware factory for types.
5+
*
6+
* In the reflection API, artifacts are specific to universes and
7+
* symbolic references used in artifacts (e.g. `scala.Int`) are resolved by mirrors.
8+
*
9+
* Therefore to build a type one needs to know a universe that the type is going to be bound to
10+
* and a mirror that is going to resolve symbolic references (e.g. to determine that `scala.Int`
11+
* points to a core class `Int` from scala-library.jar).
12+
*
13+
* `TypeCreator` implements this notion by providing a standalone type factory.
14+
*
15+
* This is immediately useful for type tags. When the compiler creates a type tag,
16+
* the end result needs to make sense in any mirror. That's because the compiler knows
17+
* the universe it's creating a type tag for (since `TypeTag` is path-dependent on a universe),
18+
* but it cannot know in advance the mirror to instantiate the result in (e.g. on JVM
19+
* it doesn't know what classloader use to resolve symbolic names in the type tag).
20+
*
21+
* Due to a typechecker restriction (no eta-expansion for dependent method types),
22+
* `TypeCreator` can't have a functional type, so it's implemented as class with an apply method.
23+
*/
424
abstract class TypeCreator {
525
def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type
626
}

0 commit comments

Comments
 (0)