pkg:api_summary
- Moved existing summary logic to the new package Change-Id: I47d032f5a253cfa32d9b685d9ff18bb08f534177 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/499440 Commit-Queue: Vijay Menon <vsm@google.com> Auto-Submit: Kevin Moore <kevmoo@google.com> Reviewed-by: Vijay Menon <vsm@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
6f45aa5329
commit
a2055fbb82
@@ -33,6 +33,7 @@ dev_dependencies:
|
||||
analysis_server_client: any
|
||||
analyzer_testing: any
|
||||
analyzer_utilities: any
|
||||
api_summary: any
|
||||
args: any
|
||||
async: any
|
||||
checks: any
|
||||
|
||||
@@ -9,9 +9,9 @@ import 'package:analyzer/dart/constant/value.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer_testing/package_root.dart' as pkg_root;
|
||||
import 'package:analyzer_utilities/src/api_summary/src/api_summary_customizer.dart';
|
||||
import 'package:analyzer_utilities/tool/api.dart';
|
||||
import 'package:analyzer_utilities/tools.dart';
|
||||
import 'package:api_summary/api_summary.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
await GeneratedContent.generateAll(pkg_root.packageRoot, allTargets);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/// Generates the file `api.txt`, which describes a package's public API.
|
||||
library;
|
||||
|
||||
import 'package:analyzer_utilities/src/api_summary/summarize_package.dart';
|
||||
import 'package:api_summary/api_summary.dart';
|
||||
import 'package:analyzer_utilities/tools.dart';
|
||||
import 'package:path/path.dart';
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ resolution: workspace
|
||||
dependencies:
|
||||
analyzer: any
|
||||
analyzer_testing: any
|
||||
api_summary: any
|
||||
collection: any
|
||||
package_config: any
|
||||
path: any
|
||||
@@ -23,4 +24,3 @@ dependencies:
|
||||
dev_dependencies:
|
||||
analyzer_plugin: any
|
||||
lints: any
|
||||
test_reflective_loader: any
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 0.1.0-wip
|
||||
|
||||
- First release.
|
||||
@@ -0,0 +1,27 @@
|
||||
Copyright 2026, the Dart project authors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,3 @@
|
||||
file:/tools/OWNERS_DEVELOPER_EXPERIENCE
|
||||
file:/tools/OWNERS_MODEL
|
||||
kevmoo@google.com
|
||||
@@ -0,0 +1 @@
|
||||
A tool to create a human-readable text summary of the public API of a Dart package. This is useful for auditing API changes with a `diff` tool.
|
||||
@@ -0,0 +1,5 @@
|
||||
include: package:dart_flutter_team_lints/analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
- unnecessary_ignore
|
||||
+4
-5
@@ -4,12 +4,11 @@
|
||||
|
||||
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
|
||||
import 'package:analyzer/file_system/physical_file_system.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/api_description.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/api_summary_customizer.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/node.dart';
|
||||
import 'src/api_description.dart';
|
||||
import 'src/api_summary_customizer.dart';
|
||||
import 'src/node.dart';
|
||||
|
||||
export 'package:analyzer_utilities/src/api_summary/src/api_summary_customizer.dart'
|
||||
show ApiSummaryCustomizer;
|
||||
export 'src/api_summary_customizer.dart' show ApiSummaryCustomizer;
|
||||
|
||||
/// Creates a human-readable text summary of the public API of a package, in a
|
||||
/// format suitable for auditing with a `diff` tool.
|
||||
+11
-10
@@ -9,14 +9,15 @@ import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/nullability_suffix.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/api_summary_customizer.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/extensions.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/member_sorting.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/node.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/unique_namer.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/uri_sorting.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'api_summary_customizer.dart';
|
||||
import 'extensions.dart';
|
||||
import 'member_sorting.dart';
|
||||
import 'node.dart';
|
||||
import 'unique_namer.dart';
|
||||
import 'uri_sorting.dart';
|
||||
|
||||
/// Data structure keeping track of a package's API while walking it to produce
|
||||
/// `api.txt`.
|
||||
class ApiDescription {
|
||||
@@ -244,7 +245,7 @@ class ApiDescription {
|
||||
var parentheticals = <List<Object?>>[];
|
||||
switch (element) {
|
||||
case TypeAliasElement(:var aliasedType, :var typeParameters):
|
||||
List<Object?> description = ['type alias'];
|
||||
var description = <Object?>['type alias'];
|
||||
if (typeParameters.isNotEmpty) {
|
||||
description.addAll(
|
||||
typeParameters
|
||||
@@ -261,7 +262,7 @@ class ApiDescription {
|
||||
:var supertype,
|
||||
:var interfaces,
|
||||
):
|
||||
List<Object?> instanceDescription = [
|
||||
var instanceDescription = <Object?>[
|
||||
switch (element) {
|
||||
ClassElement() => 'class',
|
||||
EnumElement() => 'enum',
|
||||
@@ -388,7 +389,7 @@ class ApiDescription {
|
||||
case TopLevelFunctionElement(:var type):
|
||||
parentheticals.add(['function: ', ..._describeType(type)]);
|
||||
case ExecutableElement(:var isStatic):
|
||||
String maybeStatic = isStatic ? 'static ' : '';
|
||||
var maybeStatic = isStatic ? 'static ' : '';
|
||||
switch (element) {
|
||||
case GetterElement(:var type):
|
||||
parentheticals.add([
|
||||
@@ -433,7 +434,7 @@ class ApiDescription {
|
||||
}
|
||||
}
|
||||
|
||||
/// Appends information to [node] describing [element].
|
||||
/// Appends information to [node] describing [library].
|
||||
void _dumpLibrary(LibraryElement library, Node<MemberSortKey> node) {
|
||||
var uri = library.uri;
|
||||
node.text.addAll([uri, ':']);
|
||||
+2
-1
@@ -46,7 +46,8 @@ base class ApiSummaryCustomizer {
|
||||
/// Called after [initialScanComplete] to determine if details about an
|
||||
/// element should be shown in the API summary.
|
||||
///
|
||||
/// The default behavior is to show details about elements in [topLevelPublicElements].
|
||||
/// The default behavior is to show details about elements in
|
||||
/// [topLevelPublicElements].
|
||||
bool shouldShowDetails(Element element) =>
|
||||
topLevelPublicElements.contains(element);
|
||||
}
|
||||
+3
@@ -2,6 +2,9 @@
|
||||
// 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.
|
||||
|
||||
/// @docImport 'unique_namer.dart';
|
||||
library;
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
/// Outputs the contents of [nodes] to [sink], prepending [prefix] to every
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/extensions.dart';
|
||||
import 'extensions.dart';
|
||||
|
||||
/// Object that will have a unique string representation within the context of a
|
||||
/// given [UniqueNamer] instance.
|
||||
@@ -21,9 +21,9 @@ class UniqueName {
|
||||
/// [UniqueName] from other ones with the same [_nameHint].
|
||||
int? _disambiguator;
|
||||
|
||||
UniqueName(UniqueNamer uniqueNamer, this._nameHint) {
|
||||
UniqueName(UniqueNamer uniqueNamer, this._nameHint)
|
||||
// The uniqueness guarantee depends on `_nameHint` not containing an `@`.
|
||||
assert(!_nameHint.contains('@'));
|
||||
: assert(!_nameHint.contains('@')) {
|
||||
var conflicts = uniqueNamer._conflicts[_nameHint] ??= [];
|
||||
if (conflicts.length == 1) {
|
||||
conflicts[0]._disambiguator = 1;
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
// 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_utilities/src/api_summary/src/extensions.dart';
|
||||
import 'extensions.dart';
|
||||
|
||||
/// URI categorization used by [UriSortKey].
|
||||
enum UriCategory { inPackage, notInPackage }
|
||||
@@ -0,0 +1,21 @@
|
||||
name: api_summary
|
||||
version: 0.1.0-wip
|
||||
description: Creates an API summary for a package.
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: '^3.12.0-0'
|
||||
|
||||
resolution: workspace
|
||||
|
||||
# Use 'any' constraints here; we get our versions from the DEPS file.
|
||||
dependencies:
|
||||
analyzer: any
|
||||
collection: any
|
||||
|
||||
# Use 'any' constraints here; we get our versions from the DEPS file.
|
||||
dev_dependencies:
|
||||
analyzer_testing: any
|
||||
dart_flutter_team_lints: any
|
||||
test: any
|
||||
test_reflective_loader: any
|
||||
+6
-6
@@ -8,13 +8,13 @@ import 'dart:core';
|
||||
|
||||
import 'package:analyzer/dart/analysis/analysis_context.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/api_description.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/api_summary_customizer.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/node.dart';
|
||||
import 'package:api_summary/src/api_description.dart';
|
||||
import 'package:api_summary/src/api_summary_customizer.dart';
|
||||
import 'package:api_summary/src/node.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../utilities.dart';
|
||||
import 'test_utils.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
@@ -141,8 +141,8 @@ dart:core:
|
||||
}
|
||||
|
||||
Future<void> test_field_experimental() async {
|
||||
// Marking a field as experimental causes its corresponding getter and setter
|
||||
// to be marked as experimental in the summary.
|
||||
// Marking a field as experimental causes its corresponding getter and
|
||||
// setter to be marked as experimental in the summary.
|
||||
var summary = await _build({
|
||||
'$testPackageLibPath/file.dart': '''
|
||||
import 'package:meta/meta.dart';
|
||||
+2
-2
@@ -4,11 +4,11 @@
|
||||
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:analyzer_utilities/src/api_summary/src/extensions.dart';
|
||||
import 'package:api_summary/src/extensions.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../utilities.dart';
|
||||
import 'test_utils.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
+5
-5
@@ -5,13 +5,13 @@
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/extensions.dart';
|
||||
import 'package:analyzer_utilities/src/api_summary/src/member_sorting.dart';
|
||||
import 'package:api_summary/src/extensions.dart';
|
||||
import 'package:api_summary/src/member_sorting.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../utilities.dart';
|
||||
import 'test_utils.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
@@ -183,12 +183,12 @@ typedef Z3 = int;
|
||||
required List<String> expectedOrder,
|
||||
}) {
|
||||
expect(
|
||||
elements.sortedBy((e) => MemberSortKey(e)).map((e) => e.apiName).toList(),
|
||||
elements.sortedBy(MemberSortKey.new).map((e) => e.apiName).toList(),
|
||||
expectedOrder,
|
||||
);
|
||||
expect(
|
||||
elements.reversed
|
||||
.sortedBy((e) => MemberSortKey(e))
|
||||
.sortedBy(MemberSortKey.new)
|
||||
.map((e) => e.apiName)
|
||||
.toList(),
|
||||
expectedOrder,
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:analyzer_utilities/src/api_summary/src/node.dart';
|
||||
import 'package:api_summary/src/node.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
+2
-2
@@ -4,11 +4,11 @@
|
||||
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:analyzer_utilities/src/api_summary/src/unique_namer.dart';
|
||||
import 'package:api_summary/src/unique_namer.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../utilities.dart';
|
||||
import 'test_utils.dart';
|
||||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:analyzer_utilities/src/api_summary/src/uri_sorting.dart';
|
||||
import 'package:api_summary/src/uri_sorting.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
@@ -19,6 +19,7 @@ workspace:
|
||||
- pkg/analysis_server_client
|
||||
- pkg/analysis_server_plugin
|
||||
- pkg/analyzer
|
||||
- pkg/api_summary
|
||||
- pkg/analyzer_cli
|
||||
- pkg/analyzer_plugin
|
||||
- pkg/analyzer_testing
|
||||
|
||||
@@ -2932,7 +2932,7 @@
|
||||
"name": "unit tests",
|
||||
"arguments": [
|
||||
"-nanalyzer-unittest-asserts-${mode}-${system}",
|
||||
"pkg/(analyzer|analysis_server|analysis_server_plugin|analyzer_cli|analyzer_plugin)"
|
||||
"pkg/(analyzer|analysis_server|analysis_server_plugin|analyzer_cli|analyzer_plugin|api_summary)"
|
||||
],
|
||||
"shards": 9,
|
||||
"fileset": "analyzer_unit_tests"
|
||||
@@ -3015,6 +3015,13 @@
|
||||
"pkg/analyzer_plugin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "api_summary unit tests",
|
||||
"arguments": [
|
||||
"-nanalyzer-unittest-asserts-${mode}-${system}",
|
||||
"pkg/api_summary"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "benchmark analysis server",
|
||||
"script": "out/ReleaseX64/dart-sdk/bin/dart",
|
||||
|
||||
Reference in New Issue
Block a user