Skip to content

Commit 114c006

Browse files
authored
Elements. Migrate to Element2 (#3972)
* Elements. Migrate to Element2 * address comments
1 parent 56934b7 commit 114c006

File tree

7 files changed

+103
-83
lines changed

7 files changed

+103
-83
lines changed

lib/src/generator/templates.runtime_renderers.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26267,6 +26267,7 @@ const _invisibleGetters = {
2626726267
'libraries',
2626826268
'libraryCount',
2626926269
'libraryExports',
26270+
'libraryExports2',
2627026271
'localPackages',
2627126272
'localPublicLibraries',
2627226273
'name',

lib/src/model/canonicalization.dart

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,30 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
// ignore_for_file: analyzer_use_new_elements
6-
7-
import 'package:analyzer/dart/element/element.dart';
5+
import 'package:analyzer/dart/element/element2.dart';
6+
// ignore: implementation_imports
7+
import 'package:analyzer/src/dart/element/element.dart';
88
import 'package:dartdoc/src/model/model.dart';
99
import 'package:dartdoc/src/warnings.dart';
1010

11+
const int _separatorChar = 0x3B;
12+
1113
/// Searches [PackageGraph.libraryExports] for a public, documented library
1214
/// which exports this [ModelElement], ideally in its library's package.
1315
Library? canonicalLibraryCandidate(ModelElement modelElement) {
1416
var thisAndExported =
15-
modelElement.packageGraph.libraryExports[modelElement.library.element];
17+
modelElement.packageGraph.libraryExports[modelElement.library.element2];
1618
if (thisAndExported == null) {
1719
return null;
1820
}
1921

20-
// Since we're looking for a library, find the [Element] immediately
21-
// contained by a [CompilationUnitElement] in the tree.
22-
var topLevelElement = modelElement.element;
23-
while (topLevelElement.enclosingElement3 is! LibraryElement &&
24-
topLevelElement.enclosingElement3 is! CompilationUnitElement &&
25-
topLevelElement.enclosingElement3 != null) {
26-
topLevelElement = topLevelElement.enclosingElement3!;
22+
// Since we're looking for a library, go up in the tree until we find it.
23+
var topLevelElement = modelElement.element2;
24+
while (topLevelElement.enclosingElement2 is! LibraryElement2 &&
25+
topLevelElement.enclosingElement2 != null) {
26+
topLevelElement = topLevelElement.enclosingElement2!;
2727
}
28-
var topLevelElementName = topLevelElement.name;
28+
var topLevelElementName = topLevelElement.name3;
2929
if (topLevelElementName == null) {
3030
// Any member of an unnamed extension is not public, and has no
3131
// canonical library.
@@ -36,9 +36,9 @@ Library? canonicalLibraryCandidate(ModelElement modelElement) {
3636
if (!l.isPublic) return false;
3737
if (l.package.documentedWhere == DocumentLocation.missing) return false;
3838
if (modelElement is Library) return true;
39-
var lookup = l.element.exportNamespace.definedNames[topLevelElementName];
39+
var lookup = l.element2.exportNamespace.definedNames2[topLevelElementName];
4040
return topLevelElement ==
41-
(lookup is PropertyAccessorElement ? lookup.variable2 : lookup);
41+
(lookup is PropertyAccessorElement2 ? lookup.variable3 : lookup);
4242
}).toList(growable: true);
4343

4444
if (candidateLibraries.isEmpty) {
@@ -58,7 +58,7 @@ Library? canonicalLibraryCandidate(ModelElement modelElement) {
5858
}
5959

6060
var topLevelModelElement =
61-
ModelElement.forElement(topLevelElement, modelElement.packageGraph);
61+
ModelElement.forElement2(topLevelElement, modelElement.packageGraph);
6262

6363
return _Canonicalization(topLevelModelElement)
6464
.canonicalLibraryCandidate(candidateLibraries);
@@ -74,10 +74,57 @@ final class _Canonicalization {
7474

7575
_Canonicalization(this._element);
7676

77+
/// Append an encoded form of the given [component] to the given [buffer].
78+
void _encode(StringBuffer buffer, String component) {
79+
var length = component.length;
80+
for (var i = 0; i < length; i++) {
81+
var currentChar = component.codeUnitAt(i);
82+
if (currentChar == _separatorChar) {
83+
buffer.writeCharCode(_separatorChar);
84+
}
85+
buffer.writeCharCode(currentChar);
86+
}
87+
}
88+
89+
// Copied from package analyzer ElementLocationImpl.fromElement.
90+
String _getElementLocation(Element2 element) {
91+
var components = <String>[];
92+
Element2? ancestor = element;
93+
while (ancestor != null) {
94+
if (ancestor is! ElementImpl2) {
95+
if (ancestor is LibraryElementImpl) {
96+
components.insert(0, ancestor.identifier);
97+
} else if (ancestor is AugmentableElement) {
98+
components.insert(0, ancestor.identifier);
99+
} else {
100+
throw Exception('${ancestor.runtimeType} is not an ElementImpl2');
101+
}
102+
ancestor = ancestor.enclosingElement2;
103+
} else {
104+
components.insert(0, ancestor.identifier);
105+
if (ancestor is LocalFunctionElementImpl) {
106+
ancestor = (ancestor.wrappedElement.enclosingElement2
107+
as ExecutableElementImpl)
108+
.element;
109+
} else {
110+
ancestor = ancestor.enclosingElement2;
111+
}
112+
}
113+
}
114+
var buffer = StringBuffer();
115+
var length = components.length;
116+
for (var i = 0; i < length; i++) {
117+
if (i > 0) {
118+
buffer.writeCharCode(_separatorChar);
119+
}
120+
_encode(buffer, components[i]);
121+
}
122+
return buffer.toString();
123+
}
124+
77125
/// Calculates a candidate for the canonical library of [_element], among [libraries].
78126
Library canonicalLibraryCandidate(Iterable<Library> libraries) {
79-
var locationPieces = _element.element.location
80-
.toString()
127+
var locationPieces = _getElementLocation(_element.element2)
81128
.split(_locationSplitter)
82129
.where((s) => s.isNotEmpty)
83130
.toSet();

lib/src/model/model_element.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ abstract class ModelElement
312312
TypeAliasElement(aliasedType: FunctionType()) =>
313313
FunctionTypedef(e, library, packageGraph),
314314
TypeAliasElement()
315-
when e.aliasedType.documentableElement is InterfaceElement =>
315+
when e.aliasedType.documentableElement2.asElement is InterfaceElement =>
316316
ClassTypedef(e, library, packageGraph),
317317
TypeAliasElement() => GeneralizedTypedef(e, library, packageGraph),
318318
MethodElement(isOperator: true) when enclosingContainer == null =>

lib/src/model/package_graph.dart

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'dart:collection';
88

99
import 'package:analyzer/dart/analysis/analysis_context.dart';
1010
import 'package:analyzer/dart/element/element.dart';
11+
import 'package:analyzer/dart/element/element2.dart';
1112
import 'package:analyzer/file_system/file_system.dart';
1213
import 'package:analyzer/source/source.dart';
1314
// ignore: implementation_imports
@@ -510,16 +511,16 @@ class PackageGraph with CommentReferable, Nameable {
510511
packages.where((p) => p.documentedWhere != DocumentLocation.missing);
511512

512513
/// A mapping from a [LibraryElement] to all of the [Library]s that export it.
513-
Map<LibraryElement, Set<Library>> _libraryExports = {};
514+
Map<LibraryElement2, Set<Library>> _libraryExports = {};
514515

515516
/// Marks [publicLibrary] as a library that exports [libraryElement] and all
516517
/// libraries that [libraryElement] transitively exports.
517518
///
518519
/// [alreadyTagged] is used internall to prevent visiting in cycles.
519520
void _tagExportsFor(
520521
final Library publicLibrary,
521-
final LibraryElement libraryElement, {
522-
Set<(Library, LibraryElement)>? alreadyTagged,
522+
final LibraryElement2 libraryElement, {
523+
Set<(Library, LibraryElement2)>? alreadyTagged,
523524
}) {
524525
alreadyTagged ??= {};
525526
var key = (publicLibrary, libraryElement);
@@ -529,14 +530,15 @@ class PackageGraph with CommentReferable, Nameable {
529530
alreadyTagged.add(key);
530531
// Mark that `publicLibrary` exports `libraryElement`.
531532
_libraryExports.putIfAbsent(libraryElement, () => {}).add(publicLibrary);
532-
for (var exportedElement
533-
in libraryElement.definingCompilationUnit.libraryExports) {
534-
var exportedLibrary = exportedElement.exportedLibrary;
535-
if (exportedLibrary != null) {
536-
// Follow the exports down; as `publicLibrary` exports `libraryElement`,
537-
// it also exports each `exportedLibrary`.
538-
_tagExportsFor(publicLibrary, exportedLibrary,
539-
alreadyTagged: alreadyTagged);
533+
for (var fragment in libraryElement.fragments) {
534+
for (var exportedElement in fragment.libraryExports2) {
535+
var exportedLibrary = exportedElement.exportedLibrary2;
536+
if (exportedLibrary != null) {
537+
// Follow the exports down; as `publicLibrary` exports `libraryElement`,
538+
// it also exports each `exportedLibrary`.
539+
_tagExportsFor(publicLibrary, exportedLibrary,
540+
alreadyTagged: alreadyTagged);
541+
}
540542
}
541543
}
542544
}
@@ -545,7 +547,26 @@ class PackageGraph with CommentReferable, Nameable {
545547

546548
/// A mapping from a [LibraryElement] to all of the [Library]s that export it,
547549
/// which is created if it is not yet populated.
548-
Map<LibraryElement, Set<Library>> get libraryExports {
550+
Map<LibraryElement2, Set<Library>> get libraryExports {
551+
// The map must be reset if we're still in the middle of adding libraries
552+
// (though this shouldn't happen).
553+
if (_allLibraries.keys.length != _previousSizeOfAllLibraries) {
554+
assert(
555+
_previousSizeOfAllLibraries == 0,
556+
'Re-entered `libraryExports` while building all libraries',
557+
);
558+
_previousSizeOfAllLibraries = _allLibraries.keys.length;
559+
_libraryExports = {};
560+
for (var library in publicLibraries) {
561+
_tagExportsFor(library, library.element2);
562+
}
563+
}
564+
return _libraryExports;
565+
}
566+
567+
/// A mapping from a [LibraryElement] to all of the [Library]s that export it,
568+
/// which is created if it is not yet populated.
569+
Map<LibraryElement2, Set<Library>> get libraryExports2 {
549570
// The map must be reset if we're still in the middle of adding libraries
550571
// (though this shouldn't happen).
551572
if (_allLibraries.keys.length != _previousSizeOfAllLibraries) {
@@ -556,7 +577,7 @@ class PackageGraph with CommentReferable, Nameable {
556577
_previousSizeOfAllLibraries = _allLibraries.keys.length;
557578
_libraryExports = {};
558579
for (var library in publicLibraries) {
559-
_tagExportsFor(library, library.element);
580+
_tagExportsFor(library, library.element2);
560581
}
561582
}
562583
return _libraryExports;

lib/src/type_utils.dart

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,10 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
// ignore_for_file: analyzer_use_new_elements
6-
7-
import 'package:analyzer/dart/element/element.dart';
85
import 'package:analyzer/dart/element/element2.dart';
96
import 'package:analyzer/dart/element/type.dart';
107

118
extension DartTypeExtension on DartType {
12-
/// The static element associataed with this type, where documentable, and
13-
/// `null` otherwise.
14-
///
15-
/// For example, the documentable element of [DynamicType] is `null`, as there
16-
/// is no documentation for `dynamic` which we can link to.
17-
TypeDefiningElement? get documentableElement {
18-
final self = this;
19-
return switch (self) {
20-
InterfaceType() => self.element,
21-
NeverType() => self.element as TypeDefiningElement,
22-
TypeParameterType() => self.element,
23-
_ => null
24-
};
25-
}
269

2710
/// The static element associataed with this type, where documentable, and
2811
/// `null` otherwise.

test/mustachio/builder_test_base.dart

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,11 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
// ignore_for_file: analyzer_use_new_elements
6-
75
import 'package:analyzer/dart/analysis/results.dart';
8-
import 'package:analyzer/dart/element/element.dart';
96
import 'package:analyzer/dart/element/element2.dart';
107
import 'package:analyzer/file_system/physical_file_system.dart';
118
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart'
129
show AnalysisContextCollectionImpl;
13-
import 'package:collection/collection.dart';
1410
import 'package:path/path.dart' as path;
1511
import 'package:test_descriptor/test_descriptor.dart' as d;
1612

@@ -83,26 +79,6 @@ $sourceLibraryContent
8379
root: path.join(d.sandbox, 'foo_package'));
8480
}
8581

86-
Future<LibraryElement> resolveGeneratedLibrary(String libraryPath) async {
87-
var contextCollection = AnalysisContextCollectionImpl(
88-
includedPaths: [d.sandbox],
89-
// TODO(jcollins-g): should we pass excluded directories here instead of
90-
// handling it ourselves?
91-
resourceProvider: PhysicalResourceProvider.INSTANCE,
92-
sdkPath: sdkPath,
93-
);
94-
var analysisContext = contextCollection.contextFor(d.sandbox);
95-
final libraryResult =
96-
await analysisContext.currentSession.getResolvedLibrary(libraryPath);
97-
if (libraryResult is! ResolvedLibraryResult) {
98-
throw StateError(
99-
'Expected library result to be ResolvedLibraryResult, but is '
100-
'${libraryResult.runtimeType}');
101-
}
102-
103-
return libraryResult.element;
104-
}
105-
10682
Future<LibraryElement2> resolveGeneratedLibrary2(String libraryPath) async {
10783
var contextCollection = AnalysisContextCollectionImpl(
10884
includedPaths: [d.sandbox],
@@ -121,12 +97,4 @@ Future<LibraryElement2> resolveGeneratedLibrary2(String libraryPath) async {
12197
}
12298

12399
return libraryResult.element2;
124-
}
125-
126-
extension LibraryExtensions on LibraryElement {
127-
/// Returns the top-level function in `this` library, named [name], or `null`
128-
/// if no function is found.
129-
FunctionElement? getTopLevelFunction(String name) => topLevelElements
130-
.whereType<FunctionElement>()
131-
.firstWhereOrNull((element) => element.name == name);
132-
}
100+
}

tool/mustachio/codegen_runtime_renderer.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ String buildRuntimeRenderers(Set<RendererSpec> specs, Uri sourceUri,
3030
var visibleElements = specs
3131
.map((spec) => spec.visibleTypes)
3232
.reduce((value, element) => value.union(element))
33-
.map((type) => type.documentableElement!)
33+
.map((type) => type.documentableElement2.asElement!)
3434
.toSet();
3535
var raw = RuntimeRenderersBuilder(
3636
sourceUri, typeProvider, typeSystem, visibleElements,
@@ -539,7 +539,7 @@ renderVariable:
539539
// TODO(srawlins): Find a solution for this. We can track all of the
540540
// concrete types substituted for `E` for example.
541541
if (innerType is! TypeParameterType) {
542-
var innerTypeElement = innerType.documentableElement;
542+
var innerTypeElement = innerType.documentableElement2.asElement;
543543
var renderFunctionName = _typeToRenderFunctionName[innerTypeElement];
544544
String renderCall;
545545
if (renderFunctionName == null) {

0 commit comments

Comments
 (0)