2014-10-28 1 views
2

я видел в polymer.dart они имеют:dart, как определить класс, чтобы его можно было использовать как атрибут класса?

class CustomTag { 
    final String tagName; 
    const CustomTag(this.tagName); 
} 

но как это взаимодействует с остальной частью кода? из только вышеприведенного кода я не вижу, как использование @CustomTag('my-tag') фактически что-то делает, но создает CustomTag, который затем собирает мусор, поскольку ничто не ссылается на него.

ответ

3

Чтобы ответить на вопрос в названии; они называются аннотациями; это просто конструкторы 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'] 
+0

спасибо, вы случайно не знаете, как polymer.dart отражает во всех загруженных библиотеках искать аннотациями? Я предполагаю, что это нужно сделать где-то в 'initPolymer();' но я не вижу, как он автоматически получает список всех загруженных библиотек для регистрации всех аннотаций @CustomTag. – 0xor1

+0

@ 0xor1 Я считаю, что у Полимера есть «Трансформатор»; но я боюсь, что не знаю, как это работает. –

+0

Я тоже не уверен в этом, но я думаю, что Полимер и трансформаторы обычно используют исходные зеркала и анализатор для прохождения АСТ (абстрактного синтаксического дерева) исходного кода и замены и/или добавления кода еще до того, как какой-либо код приложения казнены. –