Skip to content

Commit

Permalink
Elements. Migrate to Element2
Browse files Browse the repository at this point in the history
  • Loading branch information
keertip committed Jan 19, 2025
1 parent 021c397 commit 0bc8af0
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 45 deletions.
12 changes: 5 additions & 7 deletions lib/src/dartdoc_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// 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.

// ignore_for_file: analyzer_use_new_elements

/// dartdoc's dartdoc_options.yaml configuration file follows similar loading
/// semantics to that of analysis_options.yaml,
/// [documented here](https://dart.dev/guides/language/analysis-options).
Expand All @@ -16,7 +14,7 @@ library;

import 'dart:io' show exitCode, stderr, stdout;

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:args/args.dart';
import 'package:dartdoc/src/dartdoc.dart' show dartdocVersion, programName;
Expand Down Expand Up @@ -1130,18 +1128,18 @@ class DartdocOptionContext extends DartdocOptionContextBase
/// Build a DartdocOptionContext from an analyzer element (using its source
/// location).
factory DartdocOptionContext.fromElement(DartdocOptionSet optionSet,
LibraryElement libraryElement, ResourceProvider resourceProvider) {
LibraryElement2 libraryElement, ResourceProvider resourceProvider) {
return DartdocOptionContext(
optionSet,
resourceProvider.getFile(libraryElement.source.fullName),
resourceProvider.getFile(libraryElement.firstFragment.source.fullName),
resourceProvider);
}

/// Build a DartdocOptionContext from an existing [DartdocOptionContext] and a
/// new analyzer [Element].
/// new analyzer [Element2].
factory DartdocOptionContext.fromContextElement(
DartdocOptionContext optionContext,
LibraryElement libraryElement,
LibraryElement2 libraryElement,
ResourceProvider resourceProvider) {
return DartdocOptionContext.fromElement(
optionContext.optionSet, libraryElement, resourceProvider);
Expand Down
37 changes: 16 additions & 21 deletions lib/src/element_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
// 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.

// ignore_for_file: analyzer_use_new_elements

/// The models used to represent Dart types, all subclasses of [ElementType].
///
/// The only entrypoint for constructing these classes is [ElementType.for_].
library;

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
Expand Down Expand Up @@ -37,13 +34,13 @@ abstract class ElementType with CommentReferable, Nameable {
factory ElementType.for_(
DartType type, Library library, PackageGraph packageGraph) {
runtimeStats.incrementAccumulator('elementTypeInstantiation');
var fElement = type.documentableElement;
var fElement = type.documentableElement2;
if (fElement == null ||
fElement.kind == ElementKind.DYNAMIC ||
fElement.kind == ElementKind.NEVER) {
return UndefinedElementType._from(type, library, packageGraph);
}
var modelElement = packageGraph.getModelForElement(fElement);
var modelElement = packageGraph.getModelForElement2(fElement);
return DefinedElementType._from(type, modelElement, library, packageGraph);
}

Expand All @@ -70,7 +67,7 @@ abstract class ElementType with CommentReferable, Nameable {
String toString() => '$type';
}

/// An [ElementType] that isn't pinned to an [Element] (or one that is, but
/// An [ElementType] that isn't pinned to an [Element2] (or one that is, but
/// whose element is irrelevant).
class UndefinedElementType extends ElementType {
UndefinedElementType._(super.type, super.library, super.packageGraph)
Expand Down Expand Up @@ -105,9 +102,9 @@ class UndefinedElementType extends ElementType {
// We can not simply throw here because not all SDK libraries resolve
// all types.
if (type is InvalidType) return 'dynamic';
assert(const {'Never'}.contains(type.documentableElement?.name),
assert(const {'Never'}.contains(type.documentableElement2?.name3),
'Unrecognized type for UndefinedElementType: $type');
return type.documentableElement!.name!;
return type.documentableElement2!.name3!;
}

@override
Expand All @@ -132,15 +129,15 @@ class UndefinedElementType extends ElementType {
Iterable<CommentReferable>? get referenceGrandparentOverrides => null;
}

/// A [FunctionType] that does not have an underpinning [Element].
/// A [FunctionType] that does not have an underpinning [Element2].
class FunctionTypeElementType extends UndefinedElementType
with Rendered, Callable {
FunctionTypeElementType._(
FunctionType super.type, super.library, super.packageGraph)
: super._();

List<TypeParameter> get typeFormals => type.typeFormals
.map((p) => getModelFor(p, library) as TypeParameter)
List<TypeParameter> get typeFormals => type.typeParameters
.map((p) => getModelFor2(p, library) as TypeParameter)
.toList(growable: false);

@override
Expand Down Expand Up @@ -208,18 +205,16 @@ class ParameterizedElementType extends DefinedElementType with Rendered {

/// An [ElementType] whose underlying type was referred to by a type alias.
mixin Aliased implements ElementType {
Element get typeAliasElement => type.alias!.element;

Element2 get typeAliasElement2 => type.alias!.element2;

@override
String get name => typeAliasElement.name!;
String get name => typeAliasElement2.name3!;

@override
bool get isTypedef => true;

late final ModelElement aliasElement =
ModelElement.forElement(typeAliasElement, packageGraph);
ModelElement.forElement2(typeAliasElement2, packageGraph);

late final List<ElementType> aliasArguments = type.alias!.typeArguments
.map((f) => getTypeFor(f, library))
Expand Down Expand Up @@ -258,7 +253,7 @@ class TypeParameterElementType extends DefinedElementType {
String get nameWithGenericsPlain => '$name$nullabilitySuffix';
}

/// An [ElementType] associated with an [Element].
/// An [ElementType] associated with an [Element2].
abstract class DefinedElementType extends ElementType {
final ModelElement modelElement;

Expand All @@ -268,7 +263,7 @@ abstract class DefinedElementType extends ElementType {

factory DefinedElementType._from(DartType type, ModelElement modelElement,
Library library, PackageGraph packageGraph) {
if (type is! TypeAliasElement && type.alias != null) {
if (type is! TypeAliasElement2 && type.alias != null) {
// Here, `alias.element` signals that this is a type referring to an
// alias. (`TypeAliasElement.alias.element` has different implications.
// In that case it is an actual type alias of some kind (generic or
Expand All @@ -293,7 +288,7 @@ abstract class DefinedElementType extends ElementType {
}

@override
String get name => type.documentableElement!.name!;
String get name => type.documentableElement2!.name3!;

@override
String get fullyQualifiedName => modelElement.fullyQualifiedName;
Expand Down Expand Up @@ -327,14 +322,14 @@ abstract class DefinedElementType extends ElementType {
@internal
@override
CommentReferable get definingCommentReferable =>
ModelElement.forElement(modelElement.element, packageGraph);
ModelElement.forElement2(modelElement.element2, packageGraph);
}

/// Any callable [ElementType] will mix-in this class, whether anonymous or not,
/// unless it is an alias reference.
mixin Callable on ElementType {
List<Parameter> get parameters => type.parameters
.map((p) => getModelFor(p, library) as Parameter)
List<Parameter> get parameters => type.formalParameters
.map((p) => getModelFor2(p, library) as Parameter)
.toList(growable: false);

late final ElementType returnType = getTypeFor(type.returnType, library);
Expand Down
4 changes: 1 addition & 3 deletions lib/src/generator/generator_frontend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// 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.

// ignore_for_file: analyzer_use_new_elements

import 'package:dartdoc/src/generator/generator.dart';
import 'package:dartdoc/src/generator/generator_backend.dart';
import 'package:dartdoc/src/generator/templates.dart';
Expand Down Expand Up @@ -151,7 +149,7 @@ class GeneratorFrontEnd implements Generator {
for (var lib in package.libraries.whereDocumented) {
if (!multiplePackages) {
logInfo('Generating docs for library ${lib.breadcrumbName} from '
'${lib.element.source.uri}...');
'${lib.element2.firstFragment.source.uri}...');
}
if (!lib.isAnonymous && !lib.hasDocumentation) {
packageGraph.warnOnElement(lib, PackageWarning.noLibraryLevelDocs);
Expand Down
52 changes: 50 additions & 2 deletions lib/src/generator/templates.runtime_renderers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14112,7 +14112,7 @@ class _Renderer_LibraryContainer extends RendererBase<LibraryContainer> {
}
}

String renderLibraryRedirect(LibraryTemplateData context, Template template) {
String renderLibrary(LibraryTemplateData context, Template template) {
var buffer = StringBuffer();
_render_LibraryTemplateData(context, template.ast, template, buffer);
return buffer.toString();
Expand Down Expand Up @@ -14358,7 +14358,7 @@ class _Renderer_LibraryTemplateData extends RendererBase<LibraryTemplateData> {
}
}

String renderLibrary(LibraryTemplateData context, Template template) {
String renderLibraryRedirect(LibraryTemplateData context, Template template) {
var buffer = StringBuffer();
_render_LibraryTemplateData(context, template.ast, template, buffer);
return buffer.toString();
Expand Down Expand Up @@ -16631,6 +16631,34 @@ class _Renderer_ModelElement extends RendererBase<ModelElement> {
);
},
),
'element2': Property(
getValue: (CT_ c) => c.element2,
renderVariable:
(CT_ c, Property<CT_> self, List<String> remainingNames) =>
self.renderSimpleVariable(
c,
remainingNames,
'Element2',
),

isNullValue: (CT_ c) => false,

renderValue: (
CT_ c,
RendererBase<CT_> r,
List<MustachioNode> ast,
StringSink sink,
) {
renderSimple(
c.element2,
ast,
r.template,
sink,
parent: r,
getters: _invisibleGetters['Element2']!,
);
},
),
'enclosingElement': Property(
getValue: (CT_ c) => c.enclosingElement,
renderVariable: (
Expand Down Expand Up @@ -25825,6 +25853,26 @@ const _invisibleGetters = {
'sinceSdkVersion',
'source',
},
'Element2': {
'baseElement',
'children2',
'displayName',
'enclosingElement2',
'firstFragment',
'fragments',
'hashCode',
'id',
'isPrivate',
'isPublic',
'isSynthetic',
'kind',
'library2',
'lookupName',
'name3',
'nonSynthetic2',
'runtimeType',
'session',
},
'EnumElement': {
'augmentation',
'augmentationTarget',
Expand Down
1 change: 1 addition & 0 deletions lib/src/model/library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Library extends ModelElement
@override
final LibraryElement element;

@override
LibraryElement2 get element2 => element as LibraryElementImpl;

/// The set of [Element]s declared directly in this library.
Expand Down
16 changes: 15 additions & 1 deletion lib/src/model/model_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import 'dart:collection';
import 'dart:convert';

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart' show FunctionType;
import 'package:analyzer/source/line_info.dart';
// ignore: implementation_imports
import 'package:analyzer/src/dart/element/member.dart'
show ExecutableMember, Member, ParameterMember;
// ignore: implementation_imports
import 'package:analyzer/src/utilities/extensions/element.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/model/annotation.dart';
import 'package:dartdoc/src/model/attribute.dart';
Expand Down Expand Up @@ -109,6 +112,15 @@ abstract class ModelElement
return ModelElement.for_(e, library, p);
}

/// Returns a [ModelElement] for an [Element2], which can be a
/// property-inducing element or not.
///
/// This constructor is used when the caller does not know the element's
/// library, or whether it is property-inducing.
factory ModelElement.forElement2(Element2 e, PackageGraph p) {
return ModelElement.forElement(e.asElement!, p);
}

/// Returns a [ModelElement] for a property-inducing element.
///
/// Do not construct any [ModelElement]s except from this constructor or
Expand Down Expand Up @@ -432,7 +444,7 @@ abstract class ModelElement
@override
late final DartdocOptionContext config =
DartdocOptionContext.fromContextElement(
packageGraph.config, library.element, packageGraph.resourceProvider);
packageGraph.config, library.element2, packageGraph.resourceProvider);

bool get hasAttributes => attributes.isNotEmpty;

Expand Down Expand Up @@ -546,6 +558,8 @@ abstract class ModelElement
@override
Element get element;

Element2 get element2 => element.asElement2!;

@override
String get location {
// Call nothing from here that can emit warnings or you'll cause stack
Expand Down
25 changes: 25 additions & 0 deletions lib/src/model/nameable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
// ignore_for_file: analyzer_use_new_elements

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart' show DartType;
// ignore: implementation_imports
import 'package:analyzer/src/utilities/extensions/element.dart';
import 'package:collection/collection.dart';
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/accessor.dart';
Expand Down Expand Up @@ -66,13 +69,35 @@ mixin Nameable {
enclosingContainer: enclosingContainer,
);

/// Returns the [ModelElement] for [element], instantiating it if needed.
///
/// A convenience method for [ModelElement.for_], see its documentation.
ModelElement getModelFor2(
Element2 element,
Library library, {
Container? enclosingContainer,
}) =>
ModelElement.for_(
element.asElement!,
library,
packageGraph,
enclosingContainer: enclosingContainer,
);

/// Returns the [ModelElement] for [element], instantiating it if needed.
///
/// A convenience method for [ModelElement.forElement], see its
/// documentation.
ModelElement getModelForElement(Element element) =>
ModelElement.forElement(element, packageGraph);

/// Returns the [ModelElement] for [element], instantiating it if needed.
///
/// A convenience method for [ModelElement.forElement], see its
/// documentation.
ModelElement getModelForElement2(Element2 element) =>
ModelElement.forElement(element.asElement!, packageGraph);

/// Returns the [ModelElement] for [element], instantiating it if needed.
///
/// A convenience method for [ModelElement.forPropertyInducingElement], see
Expand Down
1 change: 1 addition & 0 deletions lib/src/model/typedef.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ abstract class Typedef extends ModelElement
@override
final TypeAliasElement element;

@override
TypeAliasElement2 get element2 => element.asElement2;

Typedef(this.element, super.library, super.packageGraph);
Expand Down
Loading

0 comments on commit 0bc8af0

Please sign in to comment.