From c8cc9c73294d10855e3f2353e492c1cd999011ea Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Tue, 8 Jul 2025 17:06:34 +0000 Subject: [PATCH 1/3] skip files with only known annotation names also --- source_gen/CHANGELOG.md | 2 + source_gen/lib/src/builder.dart | 22 ++++++-- .../test/generator_for_annotation_test.dart | 55 ++++++++++--------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/source_gen/CHANGELOG.md b/source_gen/CHANGELOG.md index d61f5cf5..1b7dc2c9 100644 --- a/source_gen/CHANGELOG.md +++ b/source_gen/CHANGELOG.md @@ -6,6 +6,8 @@ For questions please use https://github.com/dart-lang/build/discussions. - Updated the minimum package versions for a number of dependencies. - Require Dart 3.7.0 +- Update the GeneratorForAnnotation optimization to skip files with well known + annotation names such as `override`, `Deprecated`, and `pragma`. ## 2.0.0 diff --git a/source_gen/lib/src/builder.dart b/source_gen/lib/src/builder.dart index c43970c6..25bbfafd 100644 --- a/source_gen/lib/src/builder.dart +++ b/source_gen/lib/src/builder.dart @@ -93,7 +93,7 @@ class _Builder extends Builder { if (!await resolver.isLibrary(buildStep.inputId)) return; if (_generators.every((g) => g is GeneratorForAnnotation) && - !(await _hasAnyTopLevelAnnotations( + !(await _hasInterestingTopLevelAnnotations( buildStep.inputId, resolver, buildStep, @@ -382,7 +382,7 @@ Stream _generate( } } -Future _hasAnyTopLevelAnnotations( +Future _hasInterestingTopLevelAnnotations( AssetId input, Resolver resolver, BuildStep buildStep, @@ -399,16 +399,30 @@ Future _hasAnyTopLevelAnnotations( } } for (var declaration in parsed.declarations) { - if (declaration.metadata.isNotEmpty) return true; + if (declaration.metadata.any(_isUnknownAnnotation)) { + return true; + } } for (var partId in partIds) { - if (await _hasAnyTopLevelAnnotations(partId, resolver, buildStep)) { + if (await _hasInterestingTopLevelAnnotations(partId, resolver, buildStep)) { return true; } } return false; } +bool _isUnknownAnnotation(Annotation annotation) { + const knownAnnotationNames = { + // Annotations from dart:core, there is an assumption that people are not + // overriding these. + 'deprecated', + 'Deprecated', + 'override', + 'pragma', + }; + return !knownAnnotationNames.contains(annotation.name.name); +} + const defaultFileHeader = '// GENERATED CODE - DO NOT MODIFY BY HAND'; String _defaultFormatOutput(String code, Version version) => diff --git a/source_gen/test/generator_for_annotation_test.dart b/source_gen/test/generator_for_annotation_test.dart index 3e00181d..d1a03772 100644 --- a/source_gen/test/generator_for_annotation_test.dart +++ b/source_gen/test/generator_for_annotation_test.dart @@ -99,32 +99,37 @@ $dartFormatWidth } }); - test( - 'Does not resolve the library if there are no top level annotations', - () async { - final builder = LibraryBuilder( - _StubGenerator('Deprecated', elementBehavior: (_) => null), - ); - final input = AssetId('a', 'lib/a.dart'); - final assets = {input: 'main() {}'}; - - final readerWriter = - TestReaderWriter()..testing.writeString(input, assets[input]!); - - final resolver = _TestingResolver(assets); - - await runBuilder( - builder, - [input], - readerWriter, - readerWriter, - _FixedResolvers(resolver), - ); + test('Does not resolve the library if there are no interesting top level ' + 'annotations', () async { + final builder = LibraryBuilder( + _StubGenerator('Deprecated', elementBehavior: (_) => null), + ); + final input = AssetId('a', 'lib/a.dart'); + final assets = { + input: ''' +@Deprecated() +@deprecated +@override +@pragma('') +main() {}''', + }; + + final readerWriter = + TestReaderWriter()..testing.writeString(input, assets[input]!); + + final resolver = _TestingResolver(assets); + + await runBuilder( + builder, + [input], + readerWriter, + readerWriter, + _FixedResolvers(resolver), + ); - expect(resolver.parsedUnits, {input}); - expect(resolver.resolvedLibs, isEmpty); - }, - ); + expect(resolver.parsedUnits, {input}); + expect(resolver.resolvedLibs, isEmpty); + }); test('applies to annotated libraries', () async { final builder = LibraryBuilder( From 682772a7113a6c9fff318ed0add21a32061907c6 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Mon, 14 Jul 2025 18:09:12 +0000 Subject: [PATCH 2/3] fix tests that use builders relying on deprecated --- source_gen/test/builder_test.dart | 6 +++++- source_gen/test/generator_for_annotation_test.dart | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source_gen/test/builder_test.dart b/source_gen/test/builder_test.dart index 6589769c..1a42d4da 100644 --- a/source_gen/test/builder_test.dart +++ b/source_gen/test/builder_test.dart @@ -889,7 +889,11 @@ foo generated content ''', testLibPartContent: ''' part of 'test_lib.dart'; - @deprecated + + // Use this to avoid the short circuit. + const deprecated2 = deprecated; + + @deprecated2 int x; ''', ); diff --git a/source_gen/test/generator_for_annotation_test.dart b/source_gen/test/generator_for_annotation_test.dart index d1a03772..343c57be 100644 --- a/source_gen/test/generator_for_annotation_test.dart +++ b/source_gen/test/generator_for_annotation_test.dart @@ -294,13 +294,16 @@ class _StubGenerator extends GeneratorForAnnotation { const _inputMap = { 'a|lib/file.dart': ''' - @deprecated + // Use this to avoid the short circuit. + const deprecated2 = deprecated; + + @deprecated2 final foo = 'foo'; - @deprecated + @deprecated2 final bar = 'bar'; - @deprecated + @deprecated2 final baz = 'baz'; ''', }; From c2146e935c3afbb8b0acb3de32dc376924de7adc Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Mon, 14 Jul 2025 18:11:35 +0000 Subject: [PATCH 3/3] update version to -wip --- source_gen/CHANGELOG.md | 7 +++++-- source_gen/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source_gen/CHANGELOG.md b/source_gen/CHANGELOG.md index 1b7dc2c9..68d937b0 100644 --- a/source_gen/CHANGELOG.md +++ b/source_gen/CHANGELOG.md @@ -1,3 +1,8 @@ +## 3.0.0-wip + +- Update the GeneratorForAnnotation optimization to skip files with well known + annotation names such as `override`, `Deprecated`, and `pragma`. + ## 3.0.0-dev - **Breaking Change**: use the new `element2` APIs in `analyzer`. Builders that @@ -6,8 +11,6 @@ For questions please use https://github.com/dart-lang/build/discussions. - Updated the minimum package versions for a number of dependencies. - Require Dart 3.7.0 -- Update the GeneratorForAnnotation optimization to skip files with well known - annotation names such as `override`, `Deprecated`, and `pragma`. ## 2.0.0 diff --git a/source_gen/pubspec.yaml b/source_gen/pubspec.yaml index a07c7296..24759774 100644 --- a/source_gen/pubspec.yaml +++ b/source_gen/pubspec.yaml @@ -1,5 +1,5 @@ name: source_gen -version: 3.0.0-dev +version: 3.0.0-wip description: >- Source code generation builders and utilities for the Dart build system repository: https://github.com/dart-lang/source_gen/tree/master/source_gen