Improve documentation for MirrorsUsed.

BUG= http://dartbug.com/15656
R=floitsch@google.com, kathyw@google.com, lrn@google.com

Review URL: https://codereview.chromium.org//1122983002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45585 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
herhut@google.com 2015-05-07 09:08:11 +00:00
parent ba038822fb
commit 38af8ac50a

View file

@ -1196,7 +1196,7 @@ class Comment {
*
* Example usage:
*
* @MirrorsUsed(symbols: 'foo', override: '*')
* @MirrorsUsed(symbols: 'foo')
* import 'dart:mirrors';
*
* class Foo {
@ -1209,12 +1209,25 @@ class Comment {
* new Foo().foo(); // Prints "foo".
* new Foo().bar(); // Might print an arbitrary (mangled) name, "bar".
* }
*
* For a detailed description of the parameters to the [MirrorsUsed] constructor
* see the comments for [symbols], [targets], [metaTargets] and [override].
*
* An import of `dart:mirrors` may have multiple [MirrorsUsed] annotations. This
* is particularly helpful to specify overrides for specific libraries. For
* example:
*
* @MirrorsUsed(targets: 'foo.Bar', override: 'foo')
* @MirrorsUsed(targets: 'Bar')
* import 'dart:mirrors';
*
* will ensure that the target `Bar` from the current library and from library
* `foo` is available for reflection. See also [override].
*/
// TODO(ahe): Remove ", override: '*'" when it isn't necessary anymore.
class MirrorsUsed {
// Note: the fields of this class are untyped. This is because the most
// convenient way to specify to specify symbols today is using a single
// string. In some cases, a const list of classes might be convenient. Some
// convenient way to specify symbols today is using a single string. In
// some cases, a const list of classes might be convenient. Some
// might prefer to use a const list of symbols.
/**
@ -1228,19 +1241,29 @@ class MirrorsUsed {
*
* The following text is non-normative:
*
* Specifying this option turns off the following warnings emitted by
* Dart2js currently supports the following formats to specify symbols:
*
* * A constant [List] of [String] constants representing symbol names,
* e.g., `const ['foo', 'bar']`.
* * A single [String] constant whose value is a comma-separated list of
* symbol names, e.g., `"foo, bar"`.
*
* Specifying the `symbols` field turns off the following warnings emitted by
* dart2js:
*
* * Using "MirrorSystem.getName" may result in larger output.
* * Using "new #{name}" may result in larger output.
* * Using "new Symbol" may result in larger output.
*
* Use symbols = "*" to turn off the warnings mentioned above.
* For example, if you're using [noSuchMethod] to interact with a database,
* extract all the possible column names and include them in this list.
* Similarly, if you're using [noSuchMethod] to interact with another
* language (JavaScript, for example) extract all the identifiers from the
* API you use and include them in this list.
*
* For example, if using [noSuchMethod] to interact with a database, extract
* all the possible column names and include them in this list. Similarly,
* if using [noSuchMethod] to interact with another language (JavaScript, for
* example) extract all the identifiers from API used and include them in
* this list.
* Note that specifying a symbol only ensures that the symbol will be
* available under that name at runtime. It does not mark targets with
* that name as available for reflection. See [targets] and [metaTargets]
* for that purpose.
*/
final symbols;
@ -1253,16 +1276,97 @@ class MirrorsUsed {
* The following text is non-normative:
*
* For now, there is no formal description of what a reflective target is.
* Informally, it is a list of things that are expected to have fully
* functional mirrors.
* Informally, a target is a library, a class, a method or a field.
*
* Dart2js currently supports the following formats to specify targets:
*
* * A constant [List] containing [String] constants representing (qualified)
* names of targets and Dart types.
* * A single [String] constant whose value is a comma-separated list of
* (qualified) names.
* * A single Dart type.
*
* A (qualified) name is resolved to a target as follows:
*
* 1. If the qualified name matches a library name, the matching library is
* the target.
* 2. Else, find the longest prefix of the name such that the prefix ends
* just before a `.` and is a library name.
* 3. Use that library as current scope. If no matching prefix was found, use
* the current library, i.e., the library where the [MirrorsUsed]
* annotation was placed.
* 4. Split the remaining suffix (the entire name if no library name was
* found in step 3) into a list of [String] using `.` as a
* separator.
* 5. Select all targets in the current scope whose name matches a [String]
* from the list.
*
* For example:
*
* library my.library.one;
*
* class A {
* var aField;
* }
*
* library main;
*
* @MirrorsUsed(targets: "my.library.one.A.aField")
* import "dart:mirrors";
*
* The [MirrorsUsed] annotation specifies `A` and `aField` from library
* `my.library.one` as targets. This will mark the class `A` as a reflective
* target. The target specification for `aField` has no effect, as there is
* no target in `my.library.one` with that name.
*
* Note that everything within a target also is available for reflection.
* So, if a library is specified as target, all classes in that library
* become targets for reflection. Likewise, if a class is a target, all
* its methods and fields become targets for reflection. As a consequence,
* `aField` in the above example is also a reflective target.
*
*/
final targets;
/**
* A list of classes that when used as metadata indicates a reflective
* target.
* target. See also [targets].
*
* See [targets].
* The following text is non-normative:
*
* The format for specifying the list of classes is the same as used for
* specifying [targets]. However, as a library cannot be used as a metadata
* annotation in Dart, adding a library to the list of [metaTargets] has no
* effect. In particular, adding a library to [metaTargets] does not make
* the library's classes valid metadata annotations to enable reflection.
*
* If an instance of a class specified in [metaTargets] is used as
* metadata annotation on a library, class, field or method, that library,
* class, field or method is added to the set of targets for reflection.
*
* Example usage:
*
* library example;
* @MirrorsUsed(metaTargets: "example.Reflectable")
* import "dart:mirrors";
*
* class Reflectable {
* const Reflectable();
* }
*
* class Foo {
* @Reflectable()
* reflectableMethod() { ... }
*
* nonReflectableMethod() { ... }
* }
*
* In the above example. `reflectableMethod` is marked as reflectable by
* using the `Reflectable` class, which in turn is specified in the
* [metaTargets] annotation.
*
* The method `nonReflectableMethod` lacks a metadata annotation and thus
* will not be reflectable at runtime.
*/
final metaTargets;
@ -1271,10 +1375,58 @@ class MirrorsUsed {
*
* When used as metadata on an import of "dart:mirrors", this metadata does
* not apply to the library in which the annotation is used, but instead
* applies to the other libraries (all libraries if "*" is used).
* applies to the other libraries (all libraries if "*" is used).
*
* The following text is non-normative:
*
* Dart2js currently supports the following formats to specify libraries:
*
* * A constant [List] containing [String] constants representing names of
* libraries.
* * A single [String] constant whose value is a comma-separated list of
* library names.
*
* Conceptually, a [MirrorsUsed] annotation with [override] has the same
* effect as placing the annotation directly on the import of `dart:mirrors`
* in each of the referenced libraries. Thus, if the library had no
* [MirrorsUsed] annotation before, its unconditional import of
* `dart:mirrors` is overridden by an annotated import.
*
* Note that, like multiple explicit [MirrorsUsed] annotations, using
* override on a library with an existing [MirrorsUsed] annotation is
* additive. That is, the overall set of reflective targets is the union
* of the reflective targets that arise from the original and the
* overriding [MirrorsUsed] annotations.
*
* The use of [override] is only meaningful for libraries that have an
* import of `dart:mirrors` without annotation because otherwise it would
* work exactly the same way without the [override] parameter.
*
* While the annotation will apply to the given target libraries, the
* [symbols], [targets] and [metaTargets] are still evaluated in the
* scope of the annotation. Thus, to select a target from library `foo`,
* a qualified name has to be used or, if the target is visible in the
* current scope, its type may be referenced.
*
* For example, the following code marks all targets in the library `foo`
* as reflectable that have a metadata annotation using the `Reflectable`
* class from the same library.
*
* @MirrorsUsed(metaTargets: "foo.Reflectable", override: "foo")
*
* However, the following code would require the use of the `Reflectable`
* class from the current library, instead.
*
* @MirrorsUsed(metaTargets: "Reflectable", override: "foo")
*
*/
final override;
/**
* See the documentation for [MirrorsUsed.symbols], [MirrorsUsed.targets],
* [MirrorsUsed.metaTargets] and [MirrorsUsed.override] for documentation
* of the parameters.
*/
const MirrorsUsed(
{this.symbols, this.targets, this.metaTargets, this.override});
}