Чтобы ответить на вопрос в названии; они называются аннотациями; это просто конструкторы const
.
Чтобы ответить на второй вопрос; они обычно используются для оснастки (например, @deprecated
) или переписываются через Transformer
. Вы можете получить к ним доступ во время выполнения, используя mirrors
, но это, вероятно, нецелесообразно/целесообразно для веб-приложения для производства, которое преобразуется в JavaScript.
Вот некоторые примеры кода taken from this answer
import "dart:mirrors";
void main() {
var object = new Class1();
var classMirror = reflectClass(object.runtimeType);
// Retrieve 'HelloMetadata' for 'object'
HelloMetadata hello = getAnnotation(classMirror, HelloMetadata);
print("'HelloMetadata' for object: $hello");
// Retrieve 'Goodbye' for 'object.method'
var methodMirror = (reflect(object.method) as ClosureMirror).function;
Goodbye goodbye = getAnnotation(methodMirror, Goodbye);
print("'Goodbye' for object: $goodbye");
// Retrieve all 'Goodbye' for 'object.method'
List<Goodbye> goodbyes = getAnnotations(methodMirror, Goodbye);
print("'Goodbye's for object.method': $goodbyes");
// Retrieve all metadata for 'object.method'
List all = getAnnotations(methodMirror);
print("'Metadata for object.method': $all");
}
Object getAnnotation(DeclarationMirror declaration, Type annotation) {
for (var instance in declaration.metadata) {
if (instance.hasReflectee) {
var reflectee = instance.reflectee;
if (reflectee.runtimeType == annotation) {
return reflectee;
}
}
}
return null;
}
List getAnnotations(DeclarationMirror declaration, [Type annotation]) {
var result = [];
for (var instance in declaration.metadata) {
if (instance.hasReflectee) {
var reflectee = instance.reflectee;
if (annotation == null) {
result.add(reflectee);
} else if (reflectee.runtimeType == annotation) {
result.add(reflectee);
}
}
}
return result;
}
@HelloMetadata("Class1")
class Class1 {
@HelloMetadata("method")
@Goodbye("method")
@Goodbye("Class1")
void method() {
}
}
class HelloMetadata {
final String text;
const HelloMetadata(this.text);
String toString() => "Hello '$text'";
}
class Goodbye {
final String text;
const Goodbye(this.text);
String toString() => "Goodbye '$text'";
}
Выход:
'HelloMetadata' for object: Hello 'Class1'
'Goodbye' for object: Goodbye 'method'
'Goodbye's for object.method': [Goodbye 'method', Goodbye 'Class1']
'Metadata for object.method': [Hello 'method', Goodbye 'method', Goodbye 'Class1']
спасибо, вы случайно не знаете, как polymer.dart отражает во всех загруженных библиотеках искать аннотациями? Я предполагаю, что это нужно сделать где-то в 'initPolymer();' но я не вижу, как он автоматически получает список всех загруженных библиотек для регистрации всех аннотаций @CustomTag. – 0xor1
@ 0xor1 Я считаю, что у Полимера есть «Трансформатор»; но я боюсь, что не знаю, как это работает. –
Я тоже не уверен в этом, но я думаю, что Полимер и трансформаторы обычно используют исходные зеркала и анализатор для прохождения АСТ (абстрактного синтаксического дерева) исходного кода и замены и/или добавления кода еще до того, как какой-либо код приложения казнены. –