@@ -399,46 +399,63 @@ abstract class ModelElement extends Canonicalization
399399 List <String > get annotations => annotationsFromMetadata (element.metadata);
400400
401401 /// Returns linked annotations from a given metadata set, with escaping.
402+ // TODO(srawlins): Attempt to revive constructor arguments in an annotation,
403+ // akin to source_gen's Reviver, in order to link to inner components. For
404+ // example, in `@Foo(const Bar(), baz: <Baz>[Baz.one, Baz.two])`, link to
405+ // `Foo`, `Bar`, `Baz`, `Baz.one`, and `Baz.two`.
402406 List <String > annotationsFromMetadata (List <ElementAnnotation > md) {
403407 var annotationStrings = < String > [];
404408 if (md == null ) return annotationStrings;
405409 for (var a in md) {
406410 var annotation = (const HtmlEscape ()).convert (a.toSource ());
407411 var annotationElement = a.element;
408412
409- ClassElement annotationClassElement;
410- if (annotationElement is ExecutableElement ) {
413+ if (annotationElement is ConstructorElement ) {
414+ // TODO(srawlins): I think we should actually link to the constructor,
415+ // which may have details about parameters. For example, given the
416+ // annotation `@Immutable('text')`, the constructor documents what the
417+ // parameter is, and the class only references `immutable`. It's a
418+ // lose-lose cycle of mis-direction.
411419 annotationElement =
412- (annotationElement as ExecutableElement ).returnType.element;
420+ (annotationElement as ConstructorElement ).returnType.element;
421+ } else if (annotationElement is PropertyAccessorElement ) {
422+ annotationElement =
423+ (annotationElement as PropertyAccessorElement ).variable;
413424 }
414- if (annotationElement is ClassElement ) {
415- annotationClassElement = annotationElement;
425+ if (annotationElement is Member ) {
426+ annotationElement = ( annotationElement as Member ).declaration ;
416427 }
428+
429+ // Some annotations are intended to be invisible (such as `@pragma`).
430+ if (! _shouldDisplayAnnotation (annotationElement)) continue ;
431+
417432 var annotationModelElement =
418433 packageGraph.findCanonicalModelElementFor (annotationElement);
419- // annotationElement can be null if the element can't be resolved.
420- var annotationClass = packageGraph
421- .findCanonicalModelElementFor (annotationClassElement) as Class ;
422- if (annotationClass == null &&
423- annotationElement != null &&
424- annotationClassElement != null ) {
425- annotationClass =
426- ModelElement .fromElement (annotationClassElement, packageGraph)
427- as Class ;
428- }
429- // Some annotations are intended to be invisible (@pragma)
430- if (annotationClass == null ||
431- ! packageGraph.invisibleAnnotations.contains (annotationClass)) {
432- if (annotationModelElement != null ) {
433- annotation = annotation.replaceFirst (
434- annotationModelElement.name, annotationModelElement.linkedName);
435- }
436- annotationStrings.add (annotation);
434+ if (annotationModelElement != null ) {
435+ annotation = annotation.replaceFirst (
436+ annotationModelElement.name, annotationModelElement.linkedName);
437437 }
438+ annotationStrings.add (annotation);
438439 }
439440 return annotationStrings;
440441 }
441442
443+ bool _shouldDisplayAnnotation (Element annotationElement) {
444+ if (annotationElement is ClassElement ) {
445+ var annotationClass =
446+ packageGraph.findCanonicalModelElementFor (annotationElement) as Class ;
447+ if (annotationClass == null && annotationElement != null ) {
448+ annotationClass =
449+ ModelElement .fromElement (annotationElement, packageGraph) as Class ;
450+ }
451+
452+ return annotationClass == null ||
453+ packageGraph.isAnnotationVisible (annotationClass);
454+ }
455+ // We cannot resolve it, which does not prevent it from being displayed.
456+ return true ;
457+ }
458+
442459 bool _isPublic;
443460
444461 @override
@@ -506,14 +523,13 @@ abstract class ModelElement extends Canonicalization
506523 .where ((s) => s.isNotEmpty));
507524
508525 Set <String > get features {
509- var allFeatures = < String > {};
510- allFeatures.addAll (annotations);
526+ var allFeatures = < String > {...annotations};
511527
512528 // Replace the @override annotation with a feature that explicitly
513529 // indicates whether an override has occurred.
514530 allFeatures.remove ('@override' );
515531
516- // Drop the plain "deprecated" annotation, that's indicated via
532+ // Drop the plain "deprecated" annotation; that's indicated via
517533 // strikethroughs. Custom @Deprecated() will still appear.
518534 allFeatures.remove ('@deprecated' );
519535 // const and static are not needed here because const/static elements get
0 commit comments