| Index: sdk/lib/mirrors/mirrors.dart
|
| diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
|
| index 715342430186bd2824323216a6f574a61de82c7f..5d736417011b437452633ccb8771e821d9a8459a 100644
|
| --- a/sdk/lib/mirrors/mirrors.dart
|
| +++ b/sdk/lib/mirrors/mirrors.dart
|
| @@ -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].
|
| + *
|
| + * 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() { ... }
|
| *
|
| - * See [targets].
|
| + * 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});
|
| }
|
|
|