diff --git a/CHANGELOG.md b/CHANGELOG.md index 2299714c..941e3bca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,12 @@ ``` In Dart SDK `>=1.25.0` this can be relaxed as `part of` can refer to a path. + To opt-in, `GeneratorBuilder` now has a new flag, `requireLibraryDirective`. + Set it to `false`, and also set your `sdk` constraint appropriately: + + ```yaml + sdk: '>=1.25.0 <2.0.0' + ``` * Added `findType`, an utility method for `LibraryElement#getType` that also traverses `export` directives for publicly exported types. For example, to diff --git a/lib/src/builder.dart b/lib/src/builder.dart index 7aa4a148..42ab5591 100644 --- a/lib/src/builder.dart +++ b/lib/src/builder.dart @@ -39,12 +39,24 @@ class GeneratorBuilder extends Builder { /// Whether to emit a standalone (non-`part`) file in this builder. final bool isStandalone; + final bool _requireLibraryDirective; + /// Wrap [generators] to form a [Builder]-compatible API. + /// + /// May set [requireLibraryDirective] to `false` in order to opt-in to + /// supporting a `1.25.0` feature of `part of` being usable without an + /// explicit `library` directive. Developers should restrict their `pubspec` + /// accordingly: + /// ```yaml + /// sdk: '>=1.25.0 <2.0.0' + /// ``` GeneratorBuilder(this.generators, {OutputFormatter formatOutput, this.generatedExtension: '.g.dart', - this.isStandalone: false}) - : formatOutput = formatOutput ?? _formatter.format { + this.isStandalone: false, + bool requireLibraryDirective: true}) + : formatOutput = formatOutput ?? _formatter.format, + _requireLibraryDirective = requireLibraryDirective { if (generatedExtension == null) { throw new ArgumentError.notNull('generatedExtension'); } @@ -86,7 +98,11 @@ class GeneratorBuilder extends Builder { if (!isStandalone) { var asset = buildStep.inputId; - var name = nameOfPartial(library, asset); + var name = nameOfPartial( + library, + asset, + allowUnnamedPartials: !_requireLibraryDirective, + ); if (name == null) { var suggest = suggestLibraryName(asset); throw new InvalidGenerationSourceError( diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 4c17244c..069525c2 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -6,6 +6,7 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/standard_resolution_map.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:build/build.dart'; +import 'package:path/path.dart' as p; String friendlyNameForElement(Element element) { var friendlyName = element.displayName; @@ -56,7 +57,8 @@ String nameOfPartial( return element.name; } if (allowUnnamedPartials) { - return '\'package:${source.package}/${source.path}\''; + var sourceUrl = p.basename(source.uri.toString()); + return '\'$sourceUrl\''; } return null; } diff --git a/test/builder_test.dart b/test/builder_test.dart index c1248a99..234d1ab5 100644 --- a/test/builder_test.dart +++ b/test/builder_test.dart @@ -75,6 +75,14 @@ void main() { throwsA(const isInstanceOf())); }); + test('Allow no "library" when requireLibraryDirective=false', () async { + var sources = _createPackageStub(pkgName, testLibContent: 'class A {}'); + var builder = new GeneratorBuilder([const CommentGenerator()], + requireLibraryDirective: false); + await testBuilder(builder, sources, + outputs: {'$pkgName|lib/test_lib.g.dart': _testGenNoLibrary}); + }); + test( 'Simple Generator test for library', () => _generateTest( @@ -306,3 +314,15 @@ part of test_lib; // Code for "class Customer" '''; + +const _testGenNoLibrary = r'''// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'test_lib.dart'; + +// ************************************************************************** +// Generator: CommentGenerator +// Target: class A +// ************************************************************************** + +// Code for "class A" +''';