From 6b205549a84bde600e605c7d7262c7a60a323865 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 2 Sep 2025 09:31:16 -0700 Subject: [PATCH 1/3] update to the latest analyzer --- .github/workflows/corpus.yml | 2 +- pkgs/corpus/lib/api.dart | 60 ++++++++++++++++++++++++------------ pkgs/corpus/pubspec.yaml | 4 +-- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/.github/workflows/corpus.yml b/.github/workflows/corpus.yml index fe75b44d..c62ca0cd 100644 --- a/.github/workflows/corpus.yml +++ b/.github/workflows/corpus.yml @@ -26,7 +26,7 @@ jobs: strategy: fail-fast: false matrix: - sdk: [3.6, dev] + sdk: [stable, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c diff --git a/pkgs/corpus/lib/api.dart b/pkgs/corpus/lib/api.dart index 2f6880f7..f5a621a6 100644 --- a/pkgs/corpus/lib/api.dart +++ b/pkgs/corpus/lib/api.dart @@ -70,8 +70,9 @@ class ApiUsage { } static ApiUsage fromFile(PackageInfo packageInfo, File file) { - var json = const JsonDecoder().convert(file.readAsStringSync()) - as Map; + var json = + const JsonDecoder().convert(file.readAsStringSync()) + as Map; return ApiUsage( packageInfo, References.fromJson(json['packages'] as Map), @@ -106,7 +107,7 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { References referringLibraries = References(); ApiUseCollector(this.reportTarget, this.packageInfo, this.packageDir) - : packageEntity = PackageEntity(packageInfo.name); + : packageEntity = PackageEntity(packageInfo.name); String get targetName => reportTarget.name; String get targetType => reportTarget.type; @@ -143,10 +144,14 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { if (matches) { referringPackages.addLibraryReference(uri, packageEntity); - var relativeLibraryPath = - path.relative(currentFilePath, from: packageDir.path); + var relativeLibraryPath = path.relative( + currentFilePath, + from: packageDir.path, + ); referringLibraries.addLibraryReference( - uri, LibraryEntity(packageName, relativeLibraryPath)); + uri, + LibraryEntity(packageName, relativeLibraryPath), + ); } } @@ -164,7 +169,7 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { void visitSimpleIdentifier(SimpleIdentifier node) { super.visitSimpleIdentifier(node); - var element = node.staticElement; + var element = node.element; if (element == null) { return; } @@ -174,26 +179,30 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { return; } - var libraryUri = library.librarySource.uri; + var libraryUri = library.uri; if (libraryUri.scheme != targetType || libraryUri.pathSegments.first != targetName) { return; } - var enclosingElement = element.enclosingElement3!; + var enclosingElement = element.enclosingElement!; if (enclosingElement.kind == ElementKind.CLASS) { final name = enclosingElement.name!; referringPackages.addClassReference(name, packageEntity); var relPath = path.relative(currentFilePath, from: packageDir.path); referringLibraries.addClassReference( - name, LibraryEntity(packageName, relPath)); + name, + LibraryEntity(packageName, relPath), + ); } else if (enclosingElement.kind == ElementKind.EXTENSION) { final name = enclosingElement.name!; referringPackages.addExtensionReference(name, packageEntity); var relPath = path.relative(currentFilePath, from: packageDir.path); referringLibraries.addExtensionReference( - name, LibraryEntity(packageName, relPath)); + name, + LibraryEntity(packageName, relPath), + ); } if (element.kind == ElementKind.GETTER) { @@ -203,14 +212,18 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { referringPackages.addTopLevelReference(name, packageEntity); var relPath = path.relative(currentFilePath, from: packageDir.path); referringLibraries.addTopLevelReference( - name, LibraryEntity(packageName, relPath)); + name, + LibraryEntity(packageName, relPath), + ); } else if (enclosingElement.kind == ElementKind.EXTENSION) { // Record extensions. final name = enclosingElement.name!; referringPackages.addExtensionReference(name, packageEntity); var relPath = path.relative(currentFilePath, from: packageDir.path); referringLibraries.addExtensionReference( - name, LibraryEntity(packageName, relPath)); + name, + LibraryEntity(packageName, relPath), + ); } } else if (element.kind == ElementKind.FUNCTION) { if (enclosingElement.kind == ElementKind.COMPILATION_UNIT) { @@ -219,14 +232,18 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { referringPackages.addTopLevelReference(name, packageEntity); var relPath = path.relative(currentFilePath, from: packageDir.path); referringLibraries.addTopLevelReference( - name, LibraryEntity(packageName, relPath)); + name, + LibraryEntity(packageName, relPath), + ); } else if (enclosingElement.kind == ElementKind.EXTENSION) { // Record extensions. final name = enclosingElement.name!; referringPackages.addExtensionReference(name, packageEntity); var relPath = path.relative(currentFilePath, from: packageDir.path); referringLibraries.addExtensionReference( - name, LibraryEntity(packageName, relPath)); + name, + LibraryEntity(packageName, relPath), + ); } } } @@ -239,14 +256,16 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { return; } - var libraryUri = library.librarySource.uri; + var libraryUri = library.uri; if (libraryUri.scheme == targetType && libraryUri.pathSegments.first == targetName) { final name = element.name!; referringPackages.addClassReference(name, packageEntity); var relPath = path.relative(currentFilePath, from: packageDir.path); referringLibraries.addClassReference( - name, LibraryEntity(packageName, relPath)); + name, + LibraryEntity(packageName, relPath), + ); } } } @@ -322,8 +341,9 @@ class References { refs._libraryReferences.fromJson(json['library'] as Map); refs._classReferences.fromJson(json['class'] as Map); - refs._extensionReferences - .fromJson(json['extension'] as Map); + refs._extensionReferences.fromJson( + json['extension'] as Map, + ); refs._topLevelReferences.fromJson(json['topLevel'] as Map); return refs; @@ -446,7 +466,7 @@ class EntityReferences { Map toJson() { return { for (var entry in _references.entries) - entry.key: entry.value.map((entity) => entity.toJson()).toList() + entry.key: entry.value.map((entity) => entity.toJson()).toList(), }; } } diff --git a/pkgs/corpus/pubspec.yaml b/pkgs/corpus/pubspec.yaml index 50b54ebf..5e5e51a3 100644 --- a/pkgs/corpus/pubspec.yaml +++ b/pkgs/corpus/pubspec.yaml @@ -4,10 +4,10 @@ description: A tool to calculate the API usage for a package. publish_to: none environment: - sdk: ^3.6.0 + sdk: ^3.9.0 dependencies: - analyzer: ^7.0.0 + analyzer: ^8.0.0 args: ^2.1.0 cli_util: ^0.4.0 collection: ^1.19.0 From 1f554e3c20273a0eab7a1bf914c6788f82ee93a0 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 2 Sep 2025 09:33:03 -0700 Subject: [PATCH 2/3] dart format --- pkgs/corpus/bin/deps.dart | 22 +++-- pkgs/corpus/lib/packages.dart | 27 ++---- pkgs/corpus/lib/pub.dart | 37 ++++---- pkgs/corpus/lib/report.dart | 15 ++-- pkgs/corpus/lib/surveyor.dart | 9 +- pkgs/corpus/lib/usage.dart | 47 ++++++---- pkgs/corpus/test/api_test.dart | 10 ++- pkgs/corpus/test/pub_test.dart | 5 +- pkgs/corpus/test/visitor_test.dart | 140 ++++++++++++++++------------- 9 files changed, 174 insertions(+), 138 deletions(-) diff --git a/pkgs/corpus/bin/deps.dart b/pkgs/corpus/bin/deps.dart index f120a2a9..3e1126ce 100644 --- a/pkgs/corpus/bin/deps.dart +++ b/pkgs/corpus/bin/deps.dart @@ -125,7 +125,9 @@ class PackageUsageInfo { } Future getPackageUsageInfo( - Pub pub, PackageInfo package) async { + Pub pub, + PackageInfo package, +) async { var packageOptions = await pub.getPackageOptions(package.name); var packageScore = await pub.getPackageScore(package.name); @@ -146,13 +148,19 @@ File generateCsvReport( var score = usage.packageScore; return printDouble(score.grantedPoints * 100 / score.maxPoints); }), - Column('Popularity', - (usage) => printDouble(usage.packageScore.popularityScore * 100)), + Column( + 'Popularity', + (usage) => printDouble(usage.packageScore.popularityScore * 100), + ), Column('Likes', (usage) => '${usage.packageScore.likeCount}'), - Column('Constraint', - (usage) => '${usage.packageInfo.constraintFor(targetPackage.name)}'), - Column('Dep Type', - (usage) => '${usage.packageInfo.constraintType(targetPackage.name)}'), + Column( + 'Constraint', + (usage) => '${usage.packageInfo.constraintFor(targetPackage.name)}', + ), + Column( + 'Dep Type', + (usage) => '${usage.packageInfo.constraintType(targetPackage.name)}', + ), Column('SDK', (usage) => '${usage.packageInfo.sdkConstraint}'), Column('Repo', (usage) => '${usage.packageInfo.repo}'), ]; diff --git a/pkgs/corpus/lib/packages.dart b/pkgs/corpus/lib/packages.dart index b6d7c75a..8c96ca55 100644 --- a/pkgs/corpus/lib/packages.dart +++ b/pkgs/corpus/lib/packages.dart @@ -39,8 +39,9 @@ class PackageManager { return true; } - var progress = - logger?.progress('downloading ${path.basename(archiveFile.path)}'); + var progress = logger?.progress( + 'downloading ${path.basename(archiveFile.path)}', + ); try { var data = await _getPackageTarGzArchive(package); archiveFile.writeAsBytesSync(data); @@ -74,14 +75,10 @@ class PackageManager { localPackage.directory.createSync(recursive: true); - var result = await runProcess( - 'tar', - [ - '-xf', - '../../archives/${path.basename(archiveFile.path)}', - ], - workingDirectory: localPackage.directory.path, - ); + var result = await runProcess('tar', [ + '-xf', + '../../archives/${path.basename(archiveFile.path)}', + ], workingDirectory: localPackage.directory.path); if (result.exitCode != 0) { print(result.stdout); print(result.stderr); @@ -109,10 +106,7 @@ class LocalPackage { LocalPackage(this.packageInfo, this.directory); - Future pubGet({ - bool checkUpToDate = false, - Logger? logger, - }) async { + Future pubGet({bool checkUpToDate = false, Logger? logger}) async { if (checkUpToDate) { var pubspec = File(path.join(directory.path, 'pubspec.yaml')); var lock = File(path.join(directory.path, 'pubspec.lock')); @@ -138,10 +132,7 @@ class LocalPackage { final progress = logger?.progress('${path.basename(executable)} pub get'); var result = await runProcess( executable, - [ - 'pub', - 'get', - ], + ['pub', 'get'], workingDirectory: directory.path, logger: logger, ); diff --git a/pkgs/corpus/lib/pub.dart b/pkgs/corpus/lib/pub.dart index 9c89f4c3..447692a4 100644 --- a/pkgs/corpus/lib/pub.dart +++ b/pkgs/corpus/lib/pub.dart @@ -26,10 +26,7 @@ class Pub { /// Return all the packages that depend on [packageName], sorted by package /// popularity. Stream popularDependenciesOf(String packageName) { - return _packagesForSearch( - query: 'dependency:$packageName', - sort: 'top', - ); + return _packagesForSearch(query: 'dependency:$packageName', sort: 'top'); } /// Return all the pub.dev hosted packages sorted by package popularity. @@ -37,10 +34,7 @@ class Pub { /// Note that this will be tens of thousands of packages, so the caller should /// plan to limit the number of packages they iterate through. Stream allPubPackages() { - return _packagesForSearch( - query: '', - sort: 'top', - ); + return _packagesForSearch(query: '', sort: 'top'); } Future getPackageInfo(String pkgName) async { @@ -51,13 +45,15 @@ class Pub { Future getPackageOptions(String packageName) async { final json = await _getJson( - Uri.https('pub.dev', 'api/packages/$packageName/options')); + Uri.https('pub.dev', 'api/packages/$packageName/options'), + ); return PackageOptions.from(json); } Future getPackageScore(String packageName) async { - final json = - await _getJson(Uri.https('pub.dev', 'api/packages/$packageName/score')); + final json = await _getJson( + Uri.https('pub.dev', 'api/packages/$packageName/score'), + ); return PackageScore.from(json); } @@ -69,17 +65,20 @@ class Pub { final uri = Uri.parse('https://pub.dev/api/search'); for (;;) { - final targetUri = uri.replace(queryParameters: { - 'q': query, - 'page': page.toString(), - if (sort != null) 'sort': sort, - }); + final targetUri = uri.replace( + queryParameters: { + 'q': query, + 'page': page.toString(), + if (sort != null) 'sort': sort, + }, + ); final map = await _getJson(targetUri); - for (var packageName in (map['packages'] as List) - .cast>() - .map((e) => e['package'] as String?)) { + for (var packageName + in (map['packages'] as List).cast>().map( + (e) => e['package'] as String?, + )) { var packageInfo = await getPackageInfo(packageName!); yield packageInfo; diff --git a/pkgs/corpus/lib/report.dart b/pkgs/corpus/lib/report.dart index 1a5c192b..37935143 100644 --- a/pkgs/corpus/lib/report.dart +++ b/pkgs/corpus/lib/report.dart @@ -76,16 +76,21 @@ class Report { buf.writeln('## General info'); buf.writeln(); if (reportTarget is DartLibraryTarget) { - buf.writeln('https://api.dart.dev/dart-${reportTarget.name}/' - 'dart-${reportTarget.name}-library.html'); + buf.writeln( + 'https://api.dart.dev/dart-${reportTarget.name}/' + 'dart-${reportTarget.name}-library.html', + ); } else if (reportTarget is PackageTarget) { buf.writeln((reportTarget as PackageTarget).description); buf.writeln(); buf.writeln('- pub page: https://pub.dev/packages/${reportTarget.name}'); buf.writeln( - '- docs: https://pub.dev/documentation/${reportTarget.name}/latest/'); - buf.writeln('- dependent packages: ' - 'https://pub.dev/packages?q=dependency%3A${reportTarget.name}&sort=top'); + '- docs: https://pub.dev/documentation/${reportTarget.name}/latest/', + ); + buf.writeln( + '- dependent packages: ' + 'https://pub.dev/packages?q=dependency%3A${reportTarget.name}&sort=top', + ); } buf.writeln(); buf.writeln( diff --git a/pkgs/corpus/lib/surveyor.dart b/pkgs/corpus/lib/surveyor.dart index 42ea3f1f..dd1f5af3 100644 --- a/pkgs/corpus/lib/surveyor.dart +++ b/pkgs/corpus/lib/surveyor.dart @@ -23,8 +23,8 @@ class Surveyor { required List directories, this.excludedPaths = const [], }) : sourcePaths = directories - .map((directory) => path.normalize(directory.absolute.path)) - .toList() { + .map((directory) => path.normalize(directory.absolute.path)) + .toList() { assert(sourcePaths.isNotEmpty); } @@ -53,8 +53,9 @@ class Surveyor { surveyorContext._updateCurrentFilePath(filePath); try { - var resolvedUnitResult = await analysisContext.currentSession - .getResolvedUnit(filePath) as ResolvedUnitResult; + var resolvedUnitResult = + await analysisContext.currentSession.getResolvedUnit(filePath) + as ResolvedUnitResult; resolvedUnitResult.unit.accept(visitor); } catch (e) { if (!_silent) { diff --git a/pkgs/corpus/lib/usage.dart b/pkgs/corpus/lib/usage.dart index bb870640..675915b2 100644 --- a/pkgs/corpus/lib/usage.dart +++ b/pkgs/corpus/lib/usage.dart @@ -33,8 +33,10 @@ Future analyzeUsage({ ReportTarget reportTarget; if (packageName.startsWith('dart:')) { var nameWithoutPrefix = packageName.substring('dart:'.length); - reportTarget = - DartLibraryTarget(name: nameWithoutPrefix, version: sdkVersion); + reportTarget = DartLibraryTarget( + name: nameWithoutPrefix, + version: sdkVersion, + ); } else { var packageInfo = await pub.getPackageInfo(packageName); reportTarget = PackageTarget.fromPackage(packageInfo); @@ -67,8 +69,9 @@ Future analyzeUsage({ } if (!constraint.allows(Version.parse(targetPackage.version))) { log.stdout( - "skipping - version dep ($constraint) doesn't support the current " - 'stable (${targetPackage.version})'); + "skipping - version dep ($constraint) doesn't support the current " + 'stable (${targetPackage.version})', + ); continue; } } else { @@ -76,15 +79,18 @@ Future analyzeUsage({ if (sdkConstraint != null) { if (!sdkConstraint.allows(Version.parse(sdkVersion))) { log.stdout( - "skipping - sdk constraint ($sdkConstraint) doesn't support the " - 'current sdk ($sdkVersion)'); + "skipping - sdk constraint ($sdkConstraint) doesn't support the " + 'current sdk ($sdkVersion)', + ); continue; } } } - var downloadSuccess = - await packageManager.retrievePackageArchive(package, logger: log); + var downloadSuccess = await packageManager.retrievePackageArchive( + package, + logger: log, + ); if (!downloadSuccess) { log.stdout('error downloading ${package.archiveUrl}'); continue; @@ -92,8 +98,10 @@ Future analyzeUsage({ var localPackage = await packageManager.rehydratePackage(package); - var pubSuccess = - await localPackage.pubGet(checkUpToDate: true, logger: log); + var pubSuccess = await localPackage.pubGet( + checkUpToDate: true, + logger: log, + ); if (!pubSuccess) { continue; } @@ -127,10 +135,9 @@ Future analyzeUsage({ } } - var file = Report(reportTarget).generateReport( - usageInfo, - showSrcReferences: showSrcReferences, - ); + var file = Report( + reportTarget, + ).generateReport(usageInfo, showSrcReferences: showSrcReferences); log.stdout(''); log.stdout('wrote ${file.path}.'); @@ -146,11 +153,13 @@ Future _analyzePackage( Directory usingPackageDir, ) async { var cache = Cache(); - var file = File(path.join( - cache.usageDir.path, - '${reportTarget.type}-${reportTarget.name}-${reportTarget.version}', - '${analyzingPackage.name}-${analyzingPackage.version}.json', - )); + var file = File( + path.join( + cache.usageDir.path, + '${reportTarget.type}-${reportTarget.name}-${reportTarget.version}', + '${analyzingPackage.name}-${analyzingPackage.version}.json', + ), + ); if (file.existsSync()) { var usage = ApiUsage.fromFile(analyzingPackage, file); diff --git a/pkgs/corpus/test/api_test.dart b/pkgs/corpus/test/api_test.dart index 1d2d8360..61551915 100644 --- a/pkgs/corpus/test/api_test.dart +++ b/pkgs/corpus/test/api_test.dart @@ -20,8 +20,9 @@ void main() { var json = const JsonDecoder().convert(_sampleUsageJson) as Map; sampleUsage = ApiUsage( - PackageInfo.from(const JsonDecoder().convert(_packageInfoJson) - as Map), + PackageInfo.from( + const JsonDecoder().convert(_packageInfoJson) as Map, + ), References.fromJson(json['packages'] as Map), References.fromJson(json['libraries'] as Map), ); @@ -42,8 +43,9 @@ void main() { sampleUsage.toFile(tempFile); var result = ApiUsage.fromFile( - PackageInfo.from(const JsonDecoder().convert(_packageInfoJson) - as Map), + PackageInfo.from( + const JsonDecoder().convert(_packageInfoJson) as Map, + ), tempFile, ); diff --git a/pkgs/corpus/test/pub_test.dart b/pkgs/corpus/test/pub_test.dart index bd692eef..662cce11 100644 --- a/pkgs/corpus/test/pub_test.dart +++ b/pkgs/corpus/test/pub_test.dart @@ -13,8 +13,9 @@ import 'package:test/test.dart'; void main() { group('PackageInfo', () { test('parse pub.dev results', () { - var packageInfo = - PackageInfo.from(jsonDecode(_pubSampleData) as Map); + var packageInfo = PackageInfo.from( + jsonDecode(_pubSampleData) as Map, + ); check(packageInfo.name).equals('usage'); check(packageInfo.version).equals('4.0.2'); diff --git a/pkgs/corpus/test/visitor_test.dart b/pkgs/corpus/test/visitor_test.dart index 53f0e34d..9b4b95a6 100644 --- a/pkgs/corpus/test/visitor_test.dart +++ b/pkgs/corpus/test/visitor_test.dart @@ -15,10 +15,7 @@ void main() { group('ApiUseCollector - packages', () { var targetPackage = PackageInfo.from({ 'name': 'path', - 'latest': { - 'version': '0.1.2', - 'pubspec': {}, - } + 'latest': {'version': '0.1.2', 'pubspec': {}}, }); ReportTarget reportTarget = PackageTarget.fromPackage(targetPackage); var referencingPackage = PackageInfo.from({'name': 'foo'}); @@ -42,10 +39,12 @@ void main() { await surveyor.analyze(); - check(apiUsageCollector.referringPackages.sortedLibraryReferences) - .containsKey('package:path/path.dart'); - check(apiUsageCollector.referringLibraries.sortedLibraryReferences) - .containsKey('package:path/path.dart'); + check( + apiUsageCollector.referringPackages.sortedLibraryReferences, + ).containsKey('package:path/path.dart'); + check( + apiUsageCollector.referringLibraries.sortedLibraryReferences, + ).containsKey('package:path/path.dart'); }); test('class references', () async { @@ -57,27 +56,30 @@ void main() { await surveyor.analyze(); // class constructor invocation - check(apiUsageCollector.referringPackages.sortedClassReferences) - .containsKey('PosixStyle'); - check(apiUsageCollector.referringLibraries.sortedClassReferences) - .containsKey('PosixStyle'); + check( + apiUsageCollector.referringPackages.sortedClassReferences, + ).containsKey('PosixStyle'); + check( + apiUsageCollector.referringLibraries.sortedClassReferences, + ).containsKey('PosixStyle'); // class static variable reference - check(apiUsageCollector.referringPackages.sortedClassReferences) - .containsKey('Style'); - check(apiUsageCollector.referringLibraries.sortedClassReferences) - .containsKey('Style'); + check( + apiUsageCollector.referringPackages.sortedClassReferences, + ).containsKey('Style'); + check( + apiUsageCollector.referringLibraries.sortedClassReferences, + ).containsKey('Style'); }); test('extension references', () async { apiUsageCollector = ApiUseCollector( - PackageTarget.fromPackage(PackageInfo.from({ - 'name': 'collection', - 'latest': { - 'version': '0.1.2', - 'pubspec': {}, - } - })), + PackageTarget.fromPackage( + PackageInfo.from({ + 'name': 'collection', + 'latest': {'version': '0.1.2', 'pubspec': {}}, + }), + ), referencingPackage, packageDir, ); @@ -89,10 +91,12 @@ void main() { await surveyor.analyze(); - check(apiUsageCollector.referringPackages.sortedExtensionReferences) - .containsKey('IterableExtension'); - check(apiUsageCollector.referringLibraries.sortedExtensionReferences) - .containsKey('IterableExtension'); + check( + apiUsageCollector.referringPackages.sortedExtensionReferences, + ).containsKey('IterableExtension'); + check( + apiUsageCollector.referringLibraries.sortedExtensionReferences, + ).containsKey('IterableExtension'); }); test('top-level symbol references', () async { @@ -104,16 +108,20 @@ void main() { await surveyor.analyze(); // check for a top level function invokation - check(apiUsageCollector.referringPackages.sortedTopLevelReferences) - .containsKey('join'); - check(apiUsageCollector.referringLibraries.sortedTopLevelReferences) - .containsKey('join'); + check( + apiUsageCollector.referringPackages.sortedTopLevelReferences, + ).containsKey('join'); + check( + apiUsageCollector.referringLibraries.sortedTopLevelReferences, + ).containsKey('join'); // check for a top level getter reference - check(apiUsageCollector.referringPackages.sortedTopLevelReferences) - .containsKey('basename'); - check(apiUsageCollector.referringLibraries.sortedTopLevelReferences) - .containsKey('basename'); + check( + apiUsageCollector.referringPackages.sortedTopLevelReferences, + ).containsKey('basename'); + check( + apiUsageCollector.referringLibraries.sortedTopLevelReferences, + ).containsKey('basename'); }); }); @@ -143,10 +151,12 @@ void main() { await surveyor.analyze(); - check(apiUsageCollector.referringPackages.sortedLibraryReferences) - .containsKey('dart:collection'); - check(apiUsageCollector.referringLibraries.sortedLibraryReferences) - .containsKey('dart:collection'); + check( + apiUsageCollector.referringPackages.sortedLibraryReferences, + ).containsKey('dart:collection'); + check( + apiUsageCollector.referringLibraries.sortedLibraryReferences, + ).containsKey('dart:collection'); }); test('class references', () async { @@ -158,16 +168,20 @@ void main() { await surveyor.analyze(); // class constructor invocation - check(apiUsageCollector.referringPackages.sortedClassReferences) - .containsKey('SplayTreeMap'); - check(apiUsageCollector.referringLibraries.sortedClassReferences) - .containsKey('SplayTreeMap'); + check( + apiUsageCollector.referringPackages.sortedClassReferences, + ).containsKey('SplayTreeMap'); + check( + apiUsageCollector.referringLibraries.sortedClassReferences, + ).containsKey('SplayTreeMap'); // class static method reference - check(apiUsageCollector.referringPackages.sortedClassReferences) - .containsKey('Queue'); - check(apiUsageCollector.referringLibraries.sortedClassReferences) - .containsKey('Queue'); + check( + apiUsageCollector.referringPackages.sortedClassReferences, + ).containsKey('Queue'); + check( + apiUsageCollector.referringLibraries.sortedClassReferences, + ).containsKey('Queue'); }); test('top-level symbol references', () async { @@ -179,7 +193,7 @@ void main() { var surveyor = Surveyor.fromDirs( directories: [ - Directory('test/data/dart_top_level_symbol_references.dart') + Directory('test/data/dart_top_level_symbol_references.dart'), ], visitor: apiUsageCollector, ); @@ -187,16 +201,20 @@ void main() { await surveyor.analyze(); // check for a top level function invokation - check(apiUsageCollector.referringPackages.sortedTopLevelReferences) - .containsKey('jsonDecode'); - check(apiUsageCollector.referringLibraries.sortedTopLevelReferences) - .containsKey('jsonDecode'); + check( + apiUsageCollector.referringPackages.sortedTopLevelReferences, + ).containsKey('jsonDecode'); + check( + apiUsageCollector.referringLibraries.sortedTopLevelReferences, + ).containsKey('jsonDecode'); // check for a top level getter reference - check(apiUsageCollector.referringPackages.sortedTopLevelReferences) - .containsKey('base64'); - check(apiUsageCollector.referringLibraries.sortedTopLevelReferences) - .containsKey('base64'); + check( + apiUsageCollector.referringPackages.sortedTopLevelReferences, + ).containsKey('base64'); + check( + apiUsageCollector.referringLibraries.sortedTopLevelReferences, + ).containsKey('base64'); }); test('extension references', () async { @@ -213,10 +231,12 @@ void main() { await surveyor.analyze(); - check(apiUsageCollector.referringPackages.sortedExtensionReferences) - .containsKey('FutureExtensions'); - check(apiUsageCollector.referringLibraries.sortedExtensionReferences) - .containsKey('FutureExtensions'); + check( + apiUsageCollector.referringPackages.sortedExtensionReferences, + ).containsKey('FutureExtensions'); + check( + apiUsageCollector.referringLibraries.sortedExtensionReferences, + ).containsKey('FutureExtensions'); }); }); } From 62df9e9009647ff1df638bdbe5acdc66c69b778b Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 2 Sep 2025 10:25:35 -0700 Subject: [PATCH 3/3] support libraries as enclosing elements --- pkgs/corpus/lib/api.dart | 24 ++++++++++++++++++++++++ pkgs/corpus/test/visitor_test.dart | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pkgs/corpus/lib/api.dart b/pkgs/corpus/lib/api.dart index f5a621a6..7a803bb8 100644 --- a/pkgs/corpus/lib/api.dart +++ b/pkgs/corpus/lib/api.dart @@ -203,6 +203,14 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { name, LibraryEntity(packageName, relPath), ); + } else if (enclosingElement.kind == ElementKind.LIBRARY) { + final name = enclosingElement.name!; + referringPackages.addLibraryReference(name, packageEntity); + var relPath = path.relative(currentFilePath, from: packageDir.path); + referringLibraries.addLibraryReference( + name, + LibraryEntity(packageName, relPath), + ); } if (element.kind == ElementKind.GETTER) { @@ -224,6 +232,14 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { name, LibraryEntity(packageName, relPath), ); + } else if (enclosingElement.kind == ElementKind.LIBRARY) { + final name = element.name!; + referringPackages.addTopLevelReference(name, packageEntity); + var relPath = path.relative(currentFilePath, from: packageDir.path); + referringLibraries.addTopLevelReference( + name, + LibraryEntity(packageName, relPath), + ); } } else if (element.kind == ElementKind.FUNCTION) { if (enclosingElement.kind == ElementKind.COMPILATION_UNIT) { @@ -244,6 +260,14 @@ class ApiUseCollector extends RecursiveAstVisitor implements SurveyorVisitor { name, LibraryEntity(packageName, relPath), ); + } else if (enclosingElement.kind == ElementKind.LIBRARY) { + final name = element.name!; + referringPackages.addTopLevelReference(name, packageEntity); + var relPath = path.relative(currentFilePath, from: packageDir.path); + referringLibraries.addTopLevelReference( + name, + LibraryEntity(packageName, relPath), + ); } } } diff --git a/pkgs/corpus/test/visitor_test.dart b/pkgs/corpus/test/visitor_test.dart index 9b4b95a6..fc5946ec 100644 --- a/pkgs/corpus/test/visitor_test.dart +++ b/pkgs/corpus/test/visitor_test.dart @@ -107,7 +107,7 @@ void main() { await surveyor.analyze(); - // check for a top level function invokation + // check for a top level function invocation check( apiUsageCollector.referringPackages.sortedTopLevelReferences, ).containsKey('join'); @@ -200,7 +200,7 @@ void main() { await surveyor.analyze(); - // check for a top level function invokation + // check for a top level function invocation check( apiUsageCollector.referringPackages.sortedTopLevelReferences, ).containsKey('jsonDecode');