OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // For the purposes of the mirrors library, we adopt a naming | 5 // For the purposes of the mirrors library, we adopt a naming |
6 // convention with respect to getters and setters. Specifically, for | 6 // convention with respect to getters and setters. Specifically, for |
7 // some variable or field... | 7 // some variable or field... |
8 // | 8 // |
9 // var myField; | 9 // var myField; |
10 // | 10 // |
(...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1189 * | 1189 * |
1190 * The following text is non-normative: | 1190 * The following text is non-normative: |
1191 * | 1191 * |
1192 * In some scenarios, for example, when minifying Dart code, or when generating | 1192 * In some scenarios, for example, when minifying Dart code, or when generating |
1193 * JavaScript code from a Dart program, the size and performance of the output | 1193 * JavaScript code from a Dart program, the size and performance of the output |
1194 * can suffer from use of reflection. In those cases, telling the compiler | 1194 * can suffer from use of reflection. In those cases, telling the compiler |
1195 * what is used, can have a significant impact. | 1195 * what is used, can have a significant impact. |
1196 * | 1196 * |
1197 * Example usage: | 1197 * Example usage: |
1198 * | 1198 * |
1199 * @MirrorsUsed(symbols: 'foo', override: '*') | 1199 * @MirrorsUsed(symbols: 'foo') |
1200 * import 'dart:mirrors'; | 1200 * import 'dart:mirrors'; |
1201 * | 1201 * |
1202 * class Foo { | 1202 * class Foo { |
1203 * noSuchMethod(Invocation invocation) { | 1203 * noSuchMethod(Invocation invocation) { |
1204 * print(MirrorSystem.getName(invocation.memberName)); | 1204 * print(MirrorSystem.getName(invocation.memberName)); |
1205 * } | 1205 * } |
1206 * } | 1206 * } |
1207 * | 1207 * |
1208 * main() { | 1208 * main() { |
1209 * new Foo().foo(); // Prints "foo". | 1209 * new Foo().foo(); // Prints "foo". |
1210 * new Foo().bar(); // Might print an arbitrary (mangled) name, "bar". | 1210 * new Foo().bar(); // Might print an arbitrary (mangled) name, "bar". |
1211 * } | 1211 * } |
1212 * | |
1213 * For a detailed description of the parameters to the [MirrorsUsed] constructor | |
1214 * see the comments for [symbols], [targets], [metaTargets] and [override]. | |
1215 * | |
1216 * An import of `dart:mirrors` may have multiple [MirrorsUsed] annotations. This | |
1217 * is particularly helpful to specify overrides for specific libraries. For | |
1218 * example: | |
1219 * | |
1220 * @MirrorsUsed(targets: 'foo.Bar', override: 'foo') | |
1221 * @MirrorsUsed(targets: 'Bar') | |
1222 * import 'dart:mirrors'; | |
1223 * | |
1224 * will ensure that the target `Bar` from the current library and from library | |
1225 * `foo` is available for reflection. See also [override]. | |
1212 */ | 1226 */ |
1213 // TODO(ahe): Remove ", override: '*'" when it isn't necessary anymore. | |
1214 class MirrorsUsed { | 1227 class MirrorsUsed { |
1215 // Note: the fields of this class are untyped. This is because the most | 1228 // Note: the fields of this class are untyped. This is because the most |
1216 // convenient way to specify to specify symbols today is using a single | 1229 // convenient way to specify symbols today is using a single string. In |
1217 // string. In some cases, a const list of classes might be convenient. Some | 1230 // some cases, a const list of classes might be convenient. Some |
1218 // might prefer to use a const list of symbols. | 1231 // might prefer to use a const list of symbols. |
1219 | 1232 |
1220 /** | 1233 /** |
1221 * The list of strings passed to new [Symbol], and symbols that might be | 1234 * The list of strings passed to new [Symbol], and symbols that might be |
1222 * passed to [MirrorSystem.getName]. | 1235 * passed to [MirrorSystem.getName]. |
1223 * | 1236 * |
1224 * Combined with the names of [targets], [metaTargets] and their members, | 1237 * Combined with the names of [targets], [metaTargets] and their members, |
1225 * this forms the complete list of strings passed to new [Symbol], and | 1238 * this forms the complete list of strings passed to new [Symbol], and |
1226 * symbols that might be passed to [MirrorSystem.getName] by the library to | 1239 * symbols that might be passed to [MirrorSystem.getName] by the library to |
1227 * which this metadata applies. | 1240 * which this metadata applies. |
1228 * | 1241 * |
1229 * The following text is non-normative: | 1242 * The following text is non-normative: |
1230 * | 1243 * |
1231 * Specifying this option turns off the following warnings emitted by | 1244 * Dart2js currently supports the following formats to specify symbols: |
1245 * | |
1246 * * A constant [List] of [String] constants representing symbol names, | |
1247 * e.g., `const ['foo', 'bar']`. | |
1248 * * A single [String] constant whose value is a comma-separated list of | |
1249 * symbol names, e.g., `"foo, bar"`. | |
1250 * | |
1251 * Specifying the `symbols` field turns off the following warnings emitted by | |
1232 * dart2js: | 1252 * dart2js: |
1233 * | 1253 * |
1234 * * Using "MirrorSystem.getName" may result in larger output. | 1254 * * Using "MirrorSystem.getName" may result in larger output. |
1235 * * Using "new #{name}" may result in larger output. | 1255 * * Using "new #{name}" may result in larger output. |
Lasse Reichstein Nielsen
2015/05/06 20:14:20
new #{name} -> new Symbol("name") ?
I don't think
Kathy Walrath
2015/05/06 20:54:25
Is `#name` the same as `new Symbol("name")`? If so
Lasse Reichstein Nielsen
2015/05/07 06:38:14
#name is the same as 'const Symbol ("name")'. I th
herhut
2015/05/07 08:37:51
See above.
herhut
2015/05/07 08:37:51
Correct.
herhut
2015/05/07 08:37:51
Well, this is just a copy of the strings from warn
| |
1236 * | 1256 * |
1237 * Use symbols = "*" to turn off the warnings mentioned above. | 1257 * For example, if you're using [noSuchMethod] to interact with a database, |
1258 * extract all the possible column names and include them in this list. | |
1259 * Similarly, if you're using [noSuchMethod] to interact with another | |
1260 * language (JavaScript, for example) extract all the identifiers from the | |
1261 * API you use and include them in this list. | |
1238 * | 1262 * |
1239 * For example, if using [noSuchMethod] to interact with a database, extract | 1263 * Note that specifying a symbol only ensures that the symbol will be |
1240 * all the possible column names and include them in this list. Similarly, | 1264 * available under that name at runtime. It does not mark targets with |
1241 * if using [noSuchMethod] to interact with another language (JavaScript, for | 1265 * that name as available for reflection. See [targets] and [metaTargets] |
1242 * example) extract all the identifiers from API used and include them in | 1266 * for that purpose. |
1243 * this list. | |
1244 */ | 1267 */ |
1245 final symbols; | 1268 final symbols; |
1246 | 1269 |
1247 /** | 1270 /** |
1248 * A list of reflective targets. | 1271 * A list of reflective targets. |
1249 * | 1272 * |
1250 * Combined with [metaTargets], this provides the complete list of reflective | 1273 * Combined with [metaTargets], this provides the complete list of reflective |
1251 * targets used by the library to which this metadata applies. | 1274 * targets used by the library to which this metadata applies. |
1252 * | 1275 * |
1253 * The following text is non-normative: | 1276 * The following text is non-normative: |
1254 * | 1277 * |
1255 * For now, there is no formal description of what a reflective target is. | 1278 * For now, there is no formal description of what a reflective target is. |
1256 * Informally, it is a list of things that are expected to have fully | 1279 * Informally, a target is a library, a class, a method or a field. |
1257 * functional mirrors. | 1280 * |
1281 * Dart2js currently supports the following formats to specify targets: | |
1282 * | |
1283 * * A constant [List] containing [String] constants representing (qualified) | |
1284 * names of targets and Dart types. | |
1285 * * A single [String] constant whose value is a comma-separated list of | |
1286 * (qualified) names. | |
1287 * * A single Dart type. | |
1288 * | |
1289 * A (qualified) name is resolved to a target as follows: | |
1290 * | |
1291 * 1. If the qualified name matches a library name, the matching library is | |
1292 * the target. | |
1293 * 2. Else, find the longest prefix of the name such that the prefix ends | |
1294 * just before a `.` and is a library name. | |
1295 * 3. Use that library as current scope. If no matching prefix was found, use | |
1296 * the current library, i.e., the library where the [MirrorsUsed] | |
1297 * annotation was placed. | |
1298 * 4. Split the remaining suffix (the entire name if no library name was | |
1299 * found in step 3) into a list of [String] using `.` as a | |
1300 * separator. | |
1301 * 5. Select all targets in the current scope whose name matches a [String] | |
1302 * from the list. | |
1303 * | |
1304 * For example: | |
1305 * | |
1306 * library my.library.one; | |
1307 * | |
1308 * class A { | |
1309 * var aField; | |
1310 * } | |
1311 * | |
1312 * library main; | |
1313 * | |
1314 * @MirrorsUsed(targets: "my.library.one.A.aField") | |
1315 * import "dart:mirrors"; | |
1316 * | |
1317 * The [MirrorsUsed] annotation specifies `A` and `aField` from library | |
1318 * `my.library.one` as targets. This will mark the class `A` as a reflective | |
1319 * target. The target specification for `aField` has no effect, as there is | |
1320 * no target in `my.library.one` with that name. | |
1321 * | |
1322 * Note that everything within a target also is available for reflection. | |
1323 * So, if a library is specified as target, all classes in that library | |
1324 * become targets for reflection. Likewise, if a class is a target, all | |
1325 * its methods and fields become targets for reflection. As a consequence, | |
1326 * `aField` in the above example is also a reflective target. | |
1327 * | |
1258 */ | 1328 */ |
1259 final targets; | 1329 final targets; |
1260 | 1330 |
1261 /** | 1331 /** |
1262 * A list of classes that when used as metadata indicates a reflective | 1332 * A list of classes that when used as metadata indicates a reflective |
1263 * target. | 1333 * target. See also [targets]. |
1264 * | 1334 * |
1265 * See [targets]. | 1335 * The following text is non-normative: |
1336 * | |
1337 * The format for specifying the list of classes is the same as used for | |
1338 * specifying [targets]. However, as a library cannot be used as a metadata | |
1339 * annotation in Dart, adding a library to the list of [metaTargets] has no | |
1340 * effect. In particular, adding a library to [metaTargets] does not make | |
1341 * the library's classes valid metadata annotations to enable reflection. | |
1342 * | |
1343 * If an instance of a class specified in [metaTargets] is used as | |
1344 * metadata annotation on a library, class, field or method, that libary, | |
Kathy Walrath
2015/05/06 20:54:25
libary -> library
herhut
2015/05/07 08:37:51
Thanks!
| |
1345 * class, field or method is added to the set of targets for reflection. | |
1346 * | |
1347 * Example usage: | |
1348 * | |
1349 * library example; | |
1350 * @MirrorsUsed(metaTargets: "example.Reflectable") | |
1351 * import "dart:mirrors"; | |
1352 * | |
1353 * class Reflectable { | |
1354 * const Reflectable(); | |
1355 * } | |
1356 * | |
1357 * class Foo { | |
1358 * @Reflectable() | |
1359 * reflectableMethod() { ... } | |
1360 * | |
1361 * nonReflectableMethod() { ... } | |
1362 * } | |
1363 * | |
1364 * In the above example. `reflectableMethod` is marked as reflectable by | |
1365 * using the `Reflectable` class, which in turn is specified in the | |
1366 * [metaTargets] annotation. | |
1367 * | |
1368 * The method `nonReflectableMethod` lacks a metadata annotation and thus | |
1369 * will not be reflectable at runtime. | |
1266 */ | 1370 */ |
1267 final metaTargets; | 1371 final metaTargets; |
1268 | 1372 |
1269 /** | 1373 /** |
1270 * A list of library names or "*". | 1374 * A list of library names or "*". |
1271 * | 1375 * |
1272 * When used as metadata on an import of "dart:mirrors", this metadata does | 1376 * When used as metadata on an import of "dart:mirrors", this metadata does |
1273 * not apply to the library in which the annotation is used, but instead | 1377 * not apply to the library in which the annotation is used, but instead |
1274 * applies to the other libraries (all libraries if "*" is used). | 1378 * applies to the other libraries (all libraries if "*" is used). |
1379 * | |
1380 * The following text is non-normative: | |
1381 * | |
1382 * Dart2js currently supports the following formats to specify libraries: | |
1383 * | |
1384 * * A constant [List] containing [String] constants representing names of | |
1385 * libraries. | |
1386 * * A single [String] constant whose value is a comma-separated list of | |
1387 * library names. | |
1388 * | |
1389 * Conceptually, a [MirrorsUsed] annotation with [override] has the same | |
1390 * effect as placing the annotation directly on the import of `dart:mirrors` | |
1391 * in each of the referenced libraries. Thus, if the library had no | |
1392 * [MirrorsUsed] annotation before, its unconditional import of | |
1393 * `dart:mirrors` is overridden by an annotated import. | |
1394 * | |
1395 * Note that, like multiple explicit [MirrorsUsed] annotations, using | |
1396 * override on a library with an existing [MirrorsUsed] annotation is | |
1397 * additive. That is, the overall set of reflective targets is the union | |
1398 * of the reflective targets that arise from the original and the | |
1399 * overriding [MirrorsUsed] annotations. The use of [override] therefore | |
1400 * is only meaningful for libraries that have an import of `dart:mirrors` | |
1401 * without annotation. | |
Lasse Reichstein Nielsen
2015/05/06 20:14:20
... because otherwise it would work exactly the sa
herhut
2015/05/07 08:37:51
Done.
| |
1402 * | |
1403 * While the annotation will apply to the given target libraries, the | |
1404 * [symbols], [targets] and [metaTargets] are still evaluated in the | |
1405 * scope of the annotation. Thus, to select a target from library `foo`, | |
1406 * a qualified name has to be used or, if the target is visible in the | |
1407 * current scope, its type may be referenced. | |
1408 * | |
1409 * For example, the following code marks all targets in the library `foo` | |
1410 * as reflectable that have a metadata annotation using the `Reflectable` | |
1411 * class from the same library. | |
1412 * | |
1413 * @MirrorsUsed(metaTargets: "foo.Reflectable", override: "foo") | |
1414 * | |
1415 * However, the following code would require the use of the `Reflectable` | |
1416 * class from the current library, instead. | |
1417 * | |
1418 * @MirrorsUsed(metaTargets: "Reflectable", override: "foo") | |
1419 * | |
1275 */ | 1420 */ |
1276 final override; | 1421 final override; |
1277 | 1422 |
1423 /** | |
1424 * See the documentation for [MirrorsUsed.symbols], [MirrorsUsed.targets], | |
1425 * [MirrorsUsed.metaTargets] and [MirrorsUsed.override] for documentation | |
1426 * of the parameters. | |
1427 */ | |
1278 const MirrorsUsed( | 1428 const MirrorsUsed( |
1279 {this.symbols, this.targets, this.metaTargets, this.override}); | 1429 {this.symbols, this.targets, this.metaTargets, this.override}); |
1280 } | 1430 } |
OLD | NEW |