blob: f40761b9c26795893de070484a25c973b9355aa7 [file] [log] [blame]
// Copyright (c) 2019, 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:analyzer/dart/element/type.dart';
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/extension_target.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/type_utils.dart';
import 'package:meta/meta.dart';
/// Extension methods
class Extension extends Container implements EnclosedElement {
final ExtensionElement element;
late final ElementType extendedType =
modelBuilder.typeFrom(element.extendedType, library);
Extension(this.element, super.library, super.packageGraph);
/// Detect if this extension applies to every object.
bool get alwaysApplies =>
extendedType.instantiatedType is DynamicType ||
extendedType.instantiatedType is VoidType ||
bool couldApplyTo<T extends ExtensionTarget>(T c) =>
_couldApplyTo(c.modelType as DefinedElementType);
/// Whether this extension could apply to [type].
bool _couldApplyTo(DefinedElementType type) {
if (extendedType.instantiatedType is DynamicType ||
extendedType.instantiatedType is VoidType) {
return true;
var typeInstantiated = type.instantiatedType;
var extendedInstantiated = extendedType.instantiatedType;
if (typeInstantiated == extendedInstantiated) {
return true;
if (DartTypeExtension(typeInstantiated).element ==
DartTypeExtension(extendedInstantiated).element &&
extendedType.isSubtypeOf(type)) {
return true;
return extendedType.isBoundSupertypeTo(type);
Library get enclosingElement => library;
Kind get kind => Kind.extension;
late List<Method> declaredMethods = element.methods
.map((e) => modelBuilder.from(e, library) as Method)
.toList(growable: false);
String get name => == null ? '' :;
late final List<Field> declaredFields = {
Accessor? getter, setter;
final fieldGetter = field.getter;
if (fieldGetter != null) {
getter = ContainerAccessor(fieldGetter, library, packageGraph);
final fieldSetter = field.setter;
if (fieldSetter != null) {
setter = ContainerAccessor(fieldSetter, library, packageGraph);
return modelBuilder.fromPropertyInducingElement(field, library,
getter: getter, setter: setter) as Field;
}).toList(growable: false);
late final List<TypeParameter> typeParameters = element.typeParameters
.map((typeParameter) => modelBuilder.from(
as Library) as TypeParameter)
.toList(growable: false);
late final List<ModelElement> allModelElements = [
String get filePath => '${library.dirName}/${fileStructure.fileName}';
String get sidebarPath =>
Map<String, CommentReferable>? _referenceChildren;
Map<String, CommentReferable> get referenceChildren {
return _referenceChildren ??= {
// Override extendedType entries with local items.
Iterable<MapEntry<String, CommentReferable>> get extraReferenceChildren =>
const [];
String get relationshipsClass => 'clazz-relationships';