From a535f048b3235baba39a4bd2ffe82648ad208b54 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Fri, 10 Sep 2021 12:58:59 -0700 Subject: [PATCH 1/3] master->main (#2779) --- example/README.md | 2 +- lib/src/experiment_options.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/README.md b/example/README.md index c6d814e8eb..751e0513ff 100644 --- a/example/README.md +++ b/example/README.md @@ -9,7 +9,7 @@ in the Dart ecosystem. The Dart team builds docs for the [Dart API reference](https://api.dart.dev/) with each new version of the SDK, via -[this script](https://github.com/dart-lang/sdk/blob/master/tools/bots/dart_sdk.py). +[this script](https://github.com/dart-lang/sdk/blob/main/tools/bots/dart_sdk.py). Look for `BuildDartdocAPIDocs`. ## Flutter diff --git a/lib/src/experiment_options.dart b/lib/src/experiment_options.dart index 017dc942f3..47b8eb4006 100644 --- a/lib/src/experiment_options.dart +++ b/lib/src/experiment_options.dart @@ -4,7 +4,7 @@ /// /// Implementation of Dart language experiment option handling for dartdoc. -/// See https://github.com/dart-lang/sdk/blob/master/docs/process/experimental-flags.md. +/// See https://github.com/dart-lang/sdk/blob/main/docs/process/experimental-flags.md. /// library dartdoc.experiment_options; From 51776f2e32b1b04192b8cb6bf18398bb759d5889 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Fri, 10 Sep 2021 17:07:06 -0700 Subject: [PATCH 2/3] Add testing for constructor tearoffs constant rendering. (#2780) * constructor tearoffs testing * another construct that analyzer doesn't like --- test/end2end/model_special_cases_test.dart | 43 +++++++++++++++++++ .../lib/constructor_tearoffs.dart | 20 +++++++++ 2 files changed, 63 insertions(+) diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index e953a06ee4..58f982265d 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -228,6 +228,49 @@ void main() { expect(referenceLookup(A, 'new'), equals(MatchingLinkResult(null))); expect(referenceLookup(At, 'new'), equals(MatchingLinkResult(null))); }); + + test('constant rendering', () { + TopLevelVariable aFunc, + aFuncParams, + aTearOffDefaultConstructor, + aTearOffNonDefaultConstructor, + aTearOffNonDefaultConstructorInt, + aTearOffDefaultConstructorArgs; + TopLevelVariable aTearOffDefaultConstructorTypedef; + aFunc = + constructorTearoffs.constants.firstWhere((c) => c.name == 'aFunc'); + aFuncParams = constructorTearoffs.constants + .firstWhere((c) => c.name == 'aFuncParams'); + aTearOffDefaultConstructor = constructorTearoffs.constants + .firstWhere((c) => c.name == 'aTearOffDefaultConstructor'); + aTearOffNonDefaultConstructor = constructorTearoffs.constants + .firstWhere((c) => c.name == 'aTearOffNonDefaultConstructor'); + aTearOffNonDefaultConstructorInt = constructorTearoffs.constants + .firstWhere((c) => c.name == 'aTearOffNonDefaultConstructorInt'); + aTearOffDefaultConstructorArgs = constructorTearoffs.constants + .firstWhere((c) => c.name == 'aTearOffDefaultConstructorArgs'); + aTearOffDefaultConstructorTypedef = constructorTearoffs.constants + .firstWhere((c) => c.name == 'aTearOffDefaultConstructorTypedef'); + + expect(aFunc.constantValue, equals('func')); + expect(aFuncParams.constantValue, equals('funcTypeParams')); + // Does not work @ analyzer 2.2 + //expect(aFuncWithArgs.constantValue, equals('funcTypeParams<String, int>')); + + expect(aTearOffDefaultConstructor.constantValue, equals('F.new')); + expect(aTearOffNonDefaultConstructor.constantValue, + equals('F.alternative')); + expect(aTearOffNonDefaultConstructorInt.constantValue, + equals('F<int>.alternative')); + expect(aTearOffDefaultConstructorArgs.constantValue, + equals('F<String>.new')); + + expect(aTearOffDefaultConstructorTypedef.constantValue, + equals('Fstring.new')); + // Does not work @ analyzer 2.2 + //expect(aTearOffDefaultConstructorArgsTypedef.constantValue, + // equals('Ft<String>.new')); + }); }, skip: !_constructorTearoffsAllowed.allows(utils.platformVersion)); }); diff --git a/testing/test_package_experiments/lib/constructor_tearoffs.dart b/testing/test_package_experiments/lib/constructor_tearoffs.dart index 722f4e4bde..eb6d4b50bf 100644 --- a/testing/test_package_experiments/lib/constructor_tearoffs.dart +++ b/testing/test_package_experiments/lib/constructor_tearoffs.dart @@ -46,6 +46,8 @@ class F { F() { print('I too am a valid constructor invocation with this feature.'); } + + F.alternative() {} } typedef Ft = F; @@ -59,3 +61,21 @@ typedef NotAClass = Function; /// Mixins don't have constructors either, so disallow `M.new`. mixin M on C { } + +void func() {} +void funcTypeParams(T something, U different) {} + +const aFunc = func; +const aFuncParams = funcTypeParams; +// TODO(jcollins-g): does not work @ analyzer 2.2 +//const aFuncWithArgs = funcTypeParams; + +const aTearOffDefaultConstructor = F.new; +const aTearOffNonDefaultConstructor = F.alternative; +const aTearOffNonDefaultConstructorInt = F.alternative; +const aTearOffDefaultConstructorArgs = F.new; + +const aTearOffDefaultConstructorTypedef = Fstring.new; + +// TODO(jcollins-g): does not work @ analyzer 2.2 +//const aTearOffDefaultConstructorArgsTypedef = Ft.new; \ No newline at end of file From 63c384f16bfe64f5da18439697a30cfc843296cb Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Mon, 13 Sep 2021 10:33:20 -0700 Subject: [PATCH 3/3] Add a message for the package not found case to help users (#2781) * Add a message for the package not found case to help users * We don't need all of dartdoc.dart --- lib/src/model/package_graph.dart | 5 +++++ lib/src/package_meta.dart | 33 ++++++++++++++++++++++++++-- test/documentation_comment_test.dart | 15 +++++++------ test/end2end/model_test.dart | 10 +++++++++ test/src/utils.dart | 1 + 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart index e0c878e43e..121837695b 100644 --- a/lib/src/model/package_graph.dart +++ b/lib/src/model/package_graph.dart @@ -10,6 +10,7 @@ import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; import 'package:analyzer/src/generated/source_io.dart'; +import 'package:dartdoc/dartdoc.dart' show DartdocFailure; import 'package:dartdoc/src/dartdoc_options.dart'; import 'package:dartdoc/src/logging.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; @@ -63,6 +64,10 @@ class PackageGraph with CommentReferable, Nameable { var libraryElement = resolvedLibrary.element; var packageMeta = packageMetaProvider.fromElement(libraryElement, config.sdkDir); + if (packageMeta == null) { + throw DartdocFailure(packageMetaProvider.getMessageForMissingPackageMeta( + libraryElement, config)); + } var lib = Library.fromLibraryResult( resolvedLibrary, this, Package.fromPackageMeta(packageMeta, this)); packageMap[packageMeta.name].libraries.add(lib); diff --git a/lib/src/package_meta.dart b/lib/src/package_meta.dart index af7c277e4d..603a9f4e3a 100644 --- a/lib/src/package_meta.dart +++ b/lib/src/package_meta.dart @@ -44,7 +44,8 @@ final PackageMetaProvider pubPackageMetaProvider = PackageMetaProvider( .getFile(PhysicalResourceProvider.INSTANCE.pathContext .absolute(Platform.resolvedExecutable)) .parent2 - .parent2); + .parent2, + messageForMissingPackageMeta: PubPackageMeta.messageForMissingPackageMeta); /// Sets the supported way of constructing [PackageMeta] objects. /// @@ -63,15 +64,32 @@ class PackageMetaProvider { _fromElement; final PackageMeta Function(String, ResourceProvider) _fromFilename; final PackageMeta Function(Folder, ResourceProvider) _fromDir; + final String Function(LibraryElement, DartdocOptionContext) + _messageForMissingPackageMeta; PackageMeta fromElement(LibraryElement library, String s) => _fromElement(library, s, resourceProvider); + PackageMeta fromFilename(String s) => _fromFilename(s, resourceProvider); + PackageMeta fromDir(Folder dir) => _fromDir(dir, resourceProvider); + String getMessageForMissingPackageMeta( + LibraryElement library, DartdocOptionContext optionContext) => + _messageForMissingPackageMeta(library, optionContext); + PackageMetaProvider(this._fromElement, this._fromFilename, this._fromDir, this.resourceProvider, this.defaultSdkDir, - {this.defaultSdk}); + {this.defaultSdk, + Function(LibraryElement, DartdocOptionContext) + messageForMissingPackageMeta}) + : _messageForMissingPackageMeta = messageForMissingPackageMeta ?? + _defaultMessageForMissingPackageMeta; + + static String _defaultMessageForMissingPackageMeta( + LibraryElement library, DartdocOptionContext optionContext) { + return 'Unknown package for library: ${library.source.fullName}'; + } } /// Describes a single package in the context of `dartdoc`. @@ -255,6 +273,17 @@ abstract class PubPackageMeta extends PackageMeta { return _packageMetaCache[pathContext.absolute(folder.path)]; } + /// Create a helpful user error message for a case where a package can not + /// be found. + static String messageForMissingPackageMeta( + LibraryElement library, DartdocOptionContext optionContext) { + var libraryString = library.librarySource.fullName; + var dartOrFlutter = optionContext.flutterRoot == null ? 'dart' : 'flutter'; + return 'Unknown package for library: $libraryString. Consider `$dartOrFlutter pub get` and/or ' + '`$dartOrFlutter pub global deactivate dartdoc` followed by `$dartOrFlutter pub global activate dartdoc` to fix. ' + 'Also, be sure that `$dartOrFlutter analyze` completes without errors.'; + } + @override String sdkType(String flutterRootPath) { if (flutterRootPath != null) { diff --git a/test/documentation_comment_test.dart b/test/documentation_comment_test.dart index d6b5deb679..bacfea1cfb 100644 --- a/test/documentation_comment_test.dart +++ b/test/documentation_comment_test.dart @@ -44,13 +44,14 @@ void main() { sdkFolder = utils.writeMockSdkFiles(mockSdk); packageMetaProvider = PackageMetaProvider( - PubPackageMeta.fromElement, - PubPackageMeta.fromFilename, - PubPackageMeta.fromDir, - resourceProvider, - sdkFolder, - defaultSdk: mockSdk, - ); + PubPackageMeta.fromElement, + PubPackageMeta.fromFilename, + PubPackageMeta.fromDir, + resourceProvider, + sdkFolder, + defaultSdk: mockSdk, + messageForMissingPackageMeta: + PubPackageMeta.messageForMissingPackageMeta); var optionSet = await DartdocOptionSet.fromOptionGenerators( 'dartdoc', [createDartdocOptions], packageMetaProvider); optionSet.parseArguments([]); diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index 80019df082..1a64fafc9a 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -93,6 +93,16 @@ void main() { packageGraph.libraries.firstWhere((lib) => lib.name == 'base_class'); }); + group('PackageMeta and PackageGraph integration', () { + test('PackageMeta error messages generate correctly', () { + var message = packageGraph.packageMetaProvider + .getMessageForMissingPackageMeta( + fakeLibrary.element, packageGraph.config); + expect(message, contains('fake.dart')); + expect(message, contains('pub global activate dartdoc')); + }); + }); + group('triple-shift', () { Library tripleShift; Class C, E, F; diff --git a/test/src/utils.dart b/test/src/utils.dart index 0e41a0aa98..413b072244 100644 --- a/test/src/utils.dart +++ b/test/src/utils.dart @@ -93,6 +93,7 @@ PackageMetaProvider get testPackageMetaProvider { resourceProvider, sdkFolder, defaultSdk: mockSdk, + messageForMissingPackageMeta: PubPackageMeta.messageForMissingPackageMeta, ); }