diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart index 9cc17d536c..56776e7560 100644 --- a/lib/src/generator/templates.runtime_renderers.dart +++ b/lib/src/generator/templates.runtime_renderers.dart @@ -26267,6 +26267,7 @@ const _invisibleGetters = { 'libraries', 'libraryCount', 'libraryExports', + 'libraryExports2', 'localPackages', 'localPublicLibraries', 'name', diff --git a/lib/src/model/canonicalization.dart b/lib/src/model/canonicalization.dart index 806171a474..a3e4a3e83b 100644 --- a/lib/src/model/canonicalization.dart +++ b/lib/src/model/canonicalization.dart @@ -2,30 +2,30 @@ // 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:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; +// ignore: implementation_imports +import 'package:analyzer/src/dart/element/element.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/warnings.dart'; +const int _separatorChar = 0x3B; + /// Searches [PackageGraph.libraryExports] for a public, documented library /// which exports this [ModelElement], ideally in its library's package. Library? canonicalLibraryCandidate(ModelElement modelElement) { var thisAndExported = - modelElement.packageGraph.libraryExports[modelElement.library.element]; + modelElement.packageGraph.libraryExports[modelElement.library.element2]; if (thisAndExported == null) { return null; } - // Since we're looking for a library, find the [Element] immediately - // contained by a [CompilationUnitElement] in the tree. - var topLevelElement = modelElement.element; - while (topLevelElement.enclosingElement3 is! LibraryElement && - topLevelElement.enclosingElement3 is! CompilationUnitElement && - topLevelElement.enclosingElement3 != null) { - topLevelElement = topLevelElement.enclosingElement3!; + // Since we're looking for a library, go up in the tree until we find it. + var topLevelElement = modelElement.element2; + while (topLevelElement.enclosingElement2 is! LibraryElement2 && + topLevelElement.enclosingElement2 != null) { + topLevelElement = topLevelElement.enclosingElement2!; } - var topLevelElementName = topLevelElement.name; + var topLevelElementName = topLevelElement.name3; if (topLevelElementName == null) { // Any member of an unnamed extension is not public, and has no // canonical library. @@ -36,9 +36,9 @@ Library? canonicalLibraryCandidate(ModelElement modelElement) { if (!l.isPublic) return false; if (l.package.documentedWhere == DocumentLocation.missing) return false; if (modelElement is Library) return true; - var lookup = l.element.exportNamespace.definedNames[topLevelElementName]; + var lookup = l.element2.exportNamespace.definedNames2[topLevelElementName]; return topLevelElement == - (lookup is PropertyAccessorElement ? lookup.variable2 : lookup); + (lookup is PropertyAccessorElement2 ? lookup.variable3 : lookup); }).toList(growable: true); if (candidateLibraries.isEmpty) { @@ -58,7 +58,7 @@ Library? canonicalLibraryCandidate(ModelElement modelElement) { } var topLevelModelElement = - ModelElement.forElement(topLevelElement, modelElement.packageGraph); + ModelElement.forElement2(topLevelElement, modelElement.packageGraph); return _Canonicalization(topLevelModelElement) .canonicalLibraryCandidate(candidateLibraries); @@ -74,10 +74,57 @@ final class _Canonicalization { _Canonicalization(this._element); + /// Append an encoded form of the given [component] to the given [buffer]. + void _encode(StringBuffer buffer, String component) { + var length = component.length; + for (var i = 0; i < length; i++) { + var currentChar = component.codeUnitAt(i); + if (currentChar == _separatorChar) { + buffer.writeCharCode(_separatorChar); + } + buffer.writeCharCode(currentChar); + } + } + + // Copied from package analyzer ElementLocationImpl.fromElement. + String _getElementLocation(Element2 element) { + var components = []; + Element2? ancestor = element; + while (ancestor != null) { + if (ancestor is! ElementImpl2) { + if (ancestor is LibraryElementImpl) { + components.insert(0, ancestor.identifier); + } else if (ancestor is AugmentableElement) { + components.insert(0, ancestor.identifier); + } else { + throw Exception('${ancestor.runtimeType} is not an ElementImpl2'); + } + ancestor = ancestor.enclosingElement2; + } else { + components.insert(0, ancestor.identifier); + if (ancestor is LocalFunctionElementImpl) { + ancestor = (ancestor.wrappedElement.enclosingElement2 + as ExecutableElementImpl) + .element; + } else { + ancestor = ancestor.enclosingElement2; + } + } + } + var buffer = StringBuffer(); + var length = components.length; + for (var i = 0; i < length; i++) { + if (i > 0) { + buffer.writeCharCode(_separatorChar); + } + _encode(buffer, components[i]); + } + return buffer.toString(); + } + /// Calculates a candidate for the canonical library of [_element], among [libraries]. Library canonicalLibraryCandidate(Iterable libraries) { - var locationPieces = _element.element.location - .toString() + var locationPieces = _getElementLocation(_element.element2) .split(_locationSplitter) .where((s) => s.isNotEmpty) .toSet(); diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index cb26094775..35a8f093fb 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -312,7 +312,7 @@ abstract class ModelElement TypeAliasElement(aliasedType: FunctionType()) => FunctionTypedef(e, library, packageGraph), TypeAliasElement() - when e.aliasedType.documentableElement is InterfaceElement => + when e.aliasedType.documentableElement2.asElement is InterfaceElement => ClassTypedef(e, library, packageGraph), TypeAliasElement() => GeneralizedTypedef(e, library, packageGraph), MethodElement(isOperator: true) when enclosingContainer == null => diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart index cb2c3fe320..997941342a 100644 --- a/lib/src/model/package_graph.dart +++ b/lib/src/model/package_graph.dart @@ -8,6 +8,7 @@ import 'dart:collection'; import 'package:analyzer/dart/analysis/analysis_context.dart'; import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/source/source.dart'; // ignore: implementation_imports @@ -510,7 +511,7 @@ class PackageGraph with CommentReferable, Nameable { packages.where((p) => p.documentedWhere != DocumentLocation.missing); /// A mapping from a [LibraryElement] to all of the [Library]s that export it. - Map> _libraryExports = {}; + Map> _libraryExports = {}; /// Marks [publicLibrary] as a library that exports [libraryElement] and all /// libraries that [libraryElement] transitively exports. @@ -518,8 +519,8 @@ class PackageGraph with CommentReferable, Nameable { /// [alreadyTagged] is used internall to prevent visiting in cycles. void _tagExportsFor( final Library publicLibrary, - final LibraryElement libraryElement, { - Set<(Library, LibraryElement)>? alreadyTagged, + final LibraryElement2 libraryElement, { + Set<(Library, LibraryElement2)>? alreadyTagged, }) { alreadyTagged ??= {}; var key = (publicLibrary, libraryElement); @@ -529,14 +530,15 @@ class PackageGraph with CommentReferable, Nameable { alreadyTagged.add(key); // Mark that `publicLibrary` exports `libraryElement`. _libraryExports.putIfAbsent(libraryElement, () => {}).add(publicLibrary); - for (var exportedElement - in libraryElement.definingCompilationUnit.libraryExports) { - var exportedLibrary = exportedElement.exportedLibrary; - if (exportedLibrary != null) { - // Follow the exports down; as `publicLibrary` exports `libraryElement`, - // it also exports each `exportedLibrary`. - _tagExportsFor(publicLibrary, exportedLibrary, - alreadyTagged: alreadyTagged); + for (var fragment in libraryElement.fragments) { + for (var exportedElement in fragment.libraryExports2) { + var exportedLibrary = exportedElement.exportedLibrary2; + if (exportedLibrary != null) { + // Follow the exports down; as `publicLibrary` exports `libraryElement`, + // it also exports each `exportedLibrary`. + _tagExportsFor(publicLibrary, exportedLibrary, + alreadyTagged: alreadyTagged); + } } } } @@ -545,7 +547,26 @@ class PackageGraph with CommentReferable, Nameable { /// A mapping from a [LibraryElement] to all of the [Library]s that export it, /// which is created if it is not yet populated. - Map> get libraryExports { + Map> get libraryExports { + // The map must be reset if we're still in the middle of adding libraries + // (though this shouldn't happen). + if (_allLibraries.keys.length != _previousSizeOfAllLibraries) { + assert( + _previousSizeOfAllLibraries == 0, + 'Re-entered `libraryExports` while building all libraries', + ); + _previousSizeOfAllLibraries = _allLibraries.keys.length; + _libraryExports = {}; + for (var library in publicLibraries) { + _tagExportsFor(library, library.element2); + } + } + return _libraryExports; + } + + /// A mapping from a [LibraryElement] to all of the [Library]s that export it, + /// which is created if it is not yet populated. + Map> get libraryExports2 { // The map must be reset if we're still in the middle of adding libraries // (though this shouldn't happen). if (_allLibraries.keys.length != _previousSizeOfAllLibraries) { @@ -556,7 +577,7 @@ class PackageGraph with CommentReferable, Nameable { _previousSizeOfAllLibraries = _allLibraries.keys.length; _libraryExports = {}; for (var library in publicLibraries) { - _tagExportsFor(library, library.element); + _tagExportsFor(library, library.element2); } } return _libraryExports; diff --git a/lib/src/type_utils.dart b/lib/src/type_utils.dart index d9f56cd648..90152f78db 100644 --- a/lib/src/type_utils.dart +++ b/lib/src/type_utils.dart @@ -2,27 +2,10 @@ // 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:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; extension DartTypeExtension on DartType { - /// The static element associataed with this type, where documentable, and - /// `null` otherwise. - /// - /// For example, the documentable element of [DynamicType] is `null`, as there - /// is no documentation for `dynamic` which we can link to. - TypeDefiningElement? get documentableElement { - final self = this; - return switch (self) { - InterfaceType() => self.element, - NeverType() => self.element as TypeDefiningElement, - TypeParameterType() => self.element, - _ => null - }; - } /// The static element associataed with this type, where documentable, and /// `null` otherwise. diff --git a/test/mustachio/builder_test_base.dart b/test/mustachio/builder_test_base.dart index 8eb8395771..a9b6ab36b6 100644 --- a/test/mustachio/builder_test_base.dart +++ b/test/mustachio/builder_test_base.dart @@ -2,15 +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 - import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart' show AnalysisContextCollectionImpl; -import 'package:collection/collection.dart'; import 'package:path/path.dart' as path; import 'package:test_descriptor/test_descriptor.dart' as d; @@ -83,26 +79,6 @@ $sourceLibraryContent root: path.join(d.sandbox, 'foo_package')); } -Future resolveGeneratedLibrary(String libraryPath) async { - var contextCollection = AnalysisContextCollectionImpl( - includedPaths: [d.sandbox], - // TODO(jcollins-g): should we pass excluded directories here instead of - // handling it ourselves? - resourceProvider: PhysicalResourceProvider.INSTANCE, - sdkPath: sdkPath, - ); - var analysisContext = contextCollection.contextFor(d.sandbox); - final libraryResult = - await analysisContext.currentSession.getResolvedLibrary(libraryPath); - if (libraryResult is! ResolvedLibraryResult) { - throw StateError( - 'Expected library result to be ResolvedLibraryResult, but is ' - '${libraryResult.runtimeType}'); - } - - return libraryResult.element; -} - Future resolveGeneratedLibrary2(String libraryPath) async { var contextCollection = AnalysisContextCollectionImpl( includedPaths: [d.sandbox], @@ -121,12 +97,4 @@ Future resolveGeneratedLibrary2(String libraryPath) async { } return libraryResult.element2; -} - -extension LibraryExtensions on LibraryElement { - /// Returns the top-level function in `this` library, named [name], or `null` - /// if no function is found. - FunctionElement? getTopLevelFunction(String name) => topLevelElements - .whereType() - .firstWhereOrNull((element) => element.name == name); -} +} \ No newline at end of file diff --git a/tool/mustachio/codegen_runtime_renderer.dart b/tool/mustachio/codegen_runtime_renderer.dart index 3910b7a7fd..ac8fdbbf8c 100644 --- a/tool/mustachio/codegen_runtime_renderer.dart +++ b/tool/mustachio/codegen_runtime_renderer.dart @@ -30,7 +30,7 @@ String buildRuntimeRenderers(Set specs, Uri sourceUri, var visibleElements = specs .map((spec) => spec.visibleTypes) .reduce((value, element) => value.union(element)) - .map((type) => type.documentableElement!) + .map((type) => type.documentableElement2.asElement!) .toSet(); var raw = RuntimeRenderersBuilder( sourceUri, typeProvider, typeSystem, visibleElements, @@ -539,7 +539,7 @@ renderVariable: // TODO(srawlins): Find a solution for this. We can track all of the // concrete types substituted for `E` for example. if (innerType is! TypeParameterType) { - var innerTypeElement = innerType.documentableElement; + var innerTypeElement = innerType.documentableElement2.asElement; var renderFunctionName = _typeToRenderFunctionName[innerTypeElement]; String renderCall; if (renderFunctionName == null) {