annotationsFromMetadata method

List<String> annotationsFromMetadata (
  1. Iterable<ElementAnnotation> md
)

Returns linked annotations from a given metadata set, with escaping.

Implementation

// TODO(srawlins): Attempt to revive constructor arguments in an annotation,
// akin to source_gen's Reviver, in order to link to inner components. For
// example, in `@Foo(const Bar(), baz: <Baz>[Baz.one, Baz.two])`, link to
// `Foo`, `Bar`, `Baz`, `Baz.one`, and `Baz.two`.
List<String> annotationsFromMetadata(Iterable<ElementAnnotation> md) {
  var annotationStrings = <String>[];
  if (md == null) return annotationStrings;
  for (var a in md) {
    var annotation = (const HtmlEscape()).convert(a.toSource());
    var annotationElement = a.element;

    if (annotationElement is ConstructorElement) {
      // TODO(srawlins): I think we should actually link to the constructor,
      // which may have details about parameters. For example, given the
      // annotation `@Immutable('text')`, the constructor documents what the
      // parameter is, and the class only references `immutable`. It's a
      // lose-lose cycle of mis-direction.
      annotationElement =
          (annotationElement as ConstructorElement).returnType.element;
    } else if (annotationElement is PropertyAccessorElement) {
      annotationElement =
          (annotationElement as PropertyAccessorElement).variable;
    }
    if (annotationElement is Member) {
      annotationElement = (annotationElement as Member).declaration;
    }

    // Some annotations are intended to be invisible (such as `@pragma`).
    if (!_shouldDisplayAnnotation(annotationElement)) continue;

    var annotationModelElement =
        packageGraph.findCanonicalModelElementFor(annotationElement);
    if (annotationModelElement != null) {
      annotation = annotation.replaceFirst(
          annotationModelElement.name, annotationModelElement.linkedName);
    }
    annotationStrings.add(annotation);
  }
  return annotationStrings;
}