Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions source_gen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
22 changes: 18 additions & 4 deletions source_gen/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -382,7 +382,7 @@ Stream<GeneratedOutput> _generate(
}
}

Future<bool> _hasAnyTopLevelAnnotations(
Future<bool> _hasInterestingTopLevelAnnotations(
AssetId input,
Resolver resolver,
BuildStep buildStep,
Expand All @@ -399,16 +399,30 @@ Future<bool> _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) =>
Expand Down
55 changes: 30 additions & 25 deletions source_gen/test/generator_for_annotation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,32 +99,37 @@ $dartFormatWidth
}
});

test(
'Does not resolve the library if there are no top level annotations',
() async {
final builder = LibraryBuilder(
_StubGenerator<Deprecated>('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>('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(
Expand Down
Loading