blob: 8616e1289773b4d3b9461b0877fb73fc08b5e04f [file] [log] [blame]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/feature.dart';
import 'package:dartdoc/src/model/getter_setter_combo.dart';
import 'package:dartdoc/src/model/library.dart';
import 'package:dartdoc/src/model/model_object_builder.dart';
import 'package:dartdoc/src/model/package_graph.dart';
/// Represents a Dart annotation, attached to an element in the source code with
/// `@`.
class Annotation extends Feature with ModelBuilder {
final ElementAnnotation annotation;
final Library library;
@override
final PackageGraph packageGraph;
Annotation(this.annotation, this.library, this.packageGraph)
: super(annotation.element!.name!);
@override
late final String linkedNameWithParameters =
packageGraph.rendererFactory.featureRenderer.renderAnnotation(this);
@override
String get linkedName => annotation.element is PropertyAccessorElement
? modelBuilder.fromElement(annotation.element!).linkedName
// TODO(jcollins-g): consider linking to constructor instead of type?
: modelType.linkedName;
late final ElementType modelType = () {
var annotatedWith = annotation.element;
if (annotatedWith is ConstructorElement) {
return modelBuilder.typeFrom(annotatedWith.returnType, library);
} else if (annotatedWith is PropertyAccessorElement) {
return (modelBuilder.fromElement(annotatedWith.variable)
as GetterSetterCombo)
.modelType;
} else {
throw StateError(
'non-callable element used as annotation?: ${annotation.element}');
}
}();
// 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`.
/// The textual representation of the argument(s) supplied to the annotation.
late final String parameterText = () {
var source = annotation.toSource();
var startIndex = source.indexOf('(');
return source.substring(startIndex == -1 ? source.length : startIndex);
}();
@override
bool get isPublic =>
modelType.isPublic &&
modelType is DefinedElementType &&
!packageGraph.invisibleAnnotations
.contains((modelType as DefinedElementType).modelElement);
@override
bool operator ==(Object other) =>
other is Annotation && other.annotation == annotation;
@override
int get hashCode => annotation.hashCode;
@override
String get cssClassName => '';
}