diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d6eb913..db5fb0ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ * **BREAKING** removed the deprecated `requireLibraryDirective` parameter in `PartBuilder`. +* `Revivable` no longer throws a type error when attempting to revive a + reference to a top-level function or static-class method. Now is returns a + reference to that function or method, as expected. + ## 0.7.6 * `TypeChecker` now throws an `UnresolvedAnnotationException` with a more diff --git a/lib/src/constants/revive.dart b/lib/src/constants/revive.dart index c458f639..8cc40a67 100644 --- a/lib/src/constants/revive.dart +++ b/lib/src/constants/revive.dart @@ -20,8 +20,21 @@ import '../utils.dart'; /// build tool(s) using this library to surface error messages to the user. Revivable reviveInstance(DartObject object, [LibraryElement origin]) { origin ??= object.type.element.library; - var url = Uri.parse(urlOfElement(object.type.element)); - final clazz = object?.type?.element as ClassElement; + final element = object.type.element; + var url = Uri.parse(urlOfElement(element)); + if (element is FunctionElement) { + return new Revivable._( + source: url.removeFragment(), + accessor: element.name, + ); + } + if (element is MethodElement && element.isStatic) { + return new Revivable._( + source: url.removeFragment(), + accessor: '${element.enclosingElement.name}.${element.name}', + ); + } + final clazz = element as ClassElement; // Enums are not included in .definingCompilationUnit.types. if (clazz.isEnum) { for (final e in clazz.fields.where( diff --git a/pubspec.yaml b/pubspec.yaml index d77cbe6a..55de30ef 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: source_gen -version: 0.8.0-dev +version: 0.8.0 author: Dart Team description: Automated source code generation for Dart. homepage: https://github.com/dart-lang/source_gen diff --git a/test/constants_test.dart b/test/constants_test.dart index 1c6888f2..70accb9b 100644 --- a/test/constants_test.dart +++ b/test/constants_test.dart @@ -195,6 +195,8 @@ void main() { @VisibleClass.secret() @fieldOnly @ClassWithStaticField.staticField + @Wrapper(someFunction) + @Wrapper(Wrapper.someFunction) class Example {} class Int64Like { @@ -238,6 +240,14 @@ void main() { static const staticField = const ClassWithStaticField._(); const ClassWithStaticField._(); } + + class Wrapper { + static void someFunction(int x, String y) {} + final Function f; + const Wrapper(this.f); + } + + void someFunction(int x, String y) {} ''', (resolver) => resolver.findLibraryByName('test_lib')); constants = library .getType('Example') @@ -293,5 +303,17 @@ void main() { expect(fieldOnly.source.fragment, isEmpty); expect(fieldOnly.accessor, 'ClassWithStaticField.staticField'); }); + + test('should decode top-level functions', () { + final fieldOnly = constants[7].read('f').revive(); + expect(fieldOnly.source.fragment, isEmpty); + expect(fieldOnly.accessor, 'someFunction'); + }); + + test('should decode static-class functions', () { + final fieldOnly = constants[8].read('f').revive(); + expect(fieldOnly.source.fragment, isEmpty); + expect(fieldOnly.accessor, 'Wrapper.someFunction'); + }); }); } diff --git a/test/test_files/annotations.dart b/test/test_files/annotations.dart index ed58cedd..b13a0909 100644 --- a/test/test_files/annotations.dart +++ b/test/test_files/annotations.dart @@ -68,6 +68,6 @@ const objectAnnotation = const { 'null': null, 'String': 'a string', 'core type': bool, - 'imported sdk type': collection.Maps, + 'imported sdk type': collection.Queue, 'non-core type': OtherPublicAnnotationClass };