diff --git a/lib/src/generator/resource_loader.dart b/lib/src/generator/resource_loader.dart index fecef1465a..8cdde97c28 100644 --- a/lib/src/generator/resource_loader.dart +++ b/lib/src/generator/resource_loader.dart @@ -13,7 +13,7 @@ library dartdoc.resource_loader; import 'dart:async' show Future; import 'dart:convert' show utf8; -import 'package:resource/resource.dart'; +import 'package:resource/resource.dart' as resource; /// Loads a `package:` resource as a String. Future loadAsString(String path) async { @@ -29,5 +29,5 @@ Future> loadAsBytes(String path) async { } var uri = Uri.parse(path); - return await ResourceLoader.defaultLoader.readAsBytes(uri); + return await resource.ResourceLoader.defaultLoader.readAsBytes(uri); } diff --git a/lib/src/model/class.dart b/lib/src/model/class.dart index 90401e55f1..b1c068d456 100644 --- a/lib/src/model/class.dart +++ b/lib/src/model/class.dart @@ -8,8 +8,8 @@ import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/extension_target.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/model_utils.dart' as model_utils; +import 'package:dartdoc/src/quiver.dart' as quiver; import 'package:meta/meta.dart'; -import 'package:quiver/iterables.dart' as quiver; /// A [Container] defined with a `class` declaration in Dart. /// @@ -81,6 +81,7 @@ class Class extends Container quiver.concat([super.instanceOperators, inheritedOperators]); List _allModelElements; + @override List get allModelElements { _allModelElements ??= List.from( @@ -129,6 +130,7 @@ class Class extends Container bool get hasPublicConstructors => publicConstructorsSorted.isNotEmpty; List _publicConstructorsSorted; + List get publicConstructorsSorted => _publicConstructorsSorted ??= publicConstructors.toList()..sort(byName); @@ -165,7 +167,9 @@ class Class extends Container model_utils.findCanonicalFor(packageGraph.implementors[href] ?? [])); } - /*lazy final*/ List _inheritedMethods; + /*lazy final*/ + List _inheritedMethods; + Iterable get inheritedMethods { if (_inheritedMethods == null) { _inheritedMethods = []; @@ -192,7 +196,9 @@ class Class extends Container bool get hasPublicInheritedMethods => publicInheritedMethods.isNotEmpty; - /*lazy final*/ List _inheritedOperators; + /*lazy final*/ + List _inheritedOperators; + Iterable get inheritedOperators { if (_inheritedOperators == null) { _inheritedOperators = []; @@ -352,6 +358,7 @@ class Class extends Container } List _allFields; + List get allFields { if (_allFields == null) { _allFields = []; @@ -463,6 +470,7 @@ class Class extends Container } Iterable _declaredMethods; + @override Iterable get declaredMethods => _declaredMethods ??= element.methods.map((e) { @@ -470,6 +478,7 @@ class Class extends Container }); List _typeParameters; + // a stronger hash? @override List get typeParameters { @@ -481,6 +490,7 @@ class Class extends Container } Iterable _instanceFields; + @override Iterable get instanceFields => _instanceFields ??= allFields.where((f) => !f.isStatic); diff --git a/lib/src/model/comment_processable.dart b/lib/src/model/comment_processable.dart index 9d555358de..f48a662653 100644 --- a/lib/src/model/comment_processable.dart +++ b/lib/src/model/comment_processable.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:args/args.dart'; -import 'package:crypto/crypto.dart'; +import 'package:crypto/crypto.dart' as crypto; import 'package:dartdoc/src/logging.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/render/model_element_renderer.dart'; @@ -502,7 +502,7 @@ mixin CommentProcessable on Documentable, Warnable, Locatable, SourceCodeMixin { if (!config.injectHtml) return rawDocs; return rawDocs.replaceAllMapped(_htmlPattern, (match) { var fragment = match[1]; - var digest = sha1.convert(fragment.codeUnits).toString(); + var digest = crypto.sha1.convert(fragment.codeUnits).toString(); packageGraph.addHtmlFragment(digest, fragment); // The newlines are so that Markdown will pass this through without // touching it. diff --git a/lib/src/model/container.dart b/lib/src/model/container.dart index cea2609dd0..6c05b3c2f6 100644 --- a/lib/src/model/container.dart +++ b/lib/src/model/container.dart @@ -5,8 +5,8 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/model_utils.dart' as model_utils; +import 'package:dartdoc/src/quiver.dart' as quiver; import 'package:meta/meta.dart'; -import 'package:quiver/iterables.dart' as quiver; /// A [Container] represents a Dart construct that can contain methods, /// operators, and fields, such as [Class], [Enum], or [Extension]. diff --git a/lib/src/model/extension.dart b/lib/src/model/extension.dart index 0c3371e606..9432ca98c6 100644 --- a/lib/src/model/extension.dart +++ b/lib/src/model/extension.dart @@ -6,7 +6,7 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/extension_target.dart'; import 'package:dartdoc/src/model/model.dart'; -import 'package:quiver/iterables.dart' as quiver; +import 'package:dartdoc/src/quiver.dart' as quiver; /// Extension methods class Extension extends Container diff --git a/lib/src/model/library.dart b/lib/src/model/library.dart index 0ab34bdba8..e95e8d37d4 100644 --- a/lib/src/model/library.dart +++ b/lib/src/model/library.dart @@ -12,9 +12,9 @@ import 'package:analyzer/src/dart/element/inheritance_manager3.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/package_meta.dart' show PackageMeta; +import 'package:dartdoc/src/quiver.dart' as quiver; import 'package:dartdoc/src/warnings.dart'; import 'package:path/path.dart' as path; -import 'package:quiver/iterables.dart' as quiver; /// Find all hashable children of a given element that are defined in the /// [LibraryElement] given at initialization. diff --git a/lib/src/model/package_builder.dart b/lib/src/model/package_builder.dart index 0d717cb34b..44ecb5919c 100644 --- a/lib/src/model/package_builder.dart +++ b/lib/src/model/package_builder.dart @@ -28,11 +28,11 @@ import 'package:dartdoc/src/logging.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/package_meta.dart' show PackageMeta, pubPackageMetaProvider; +import 'package:dartdoc/src/quiver.dart' as quiver; import 'package:dartdoc/src/render/renderer_factory.dart'; import 'package:dartdoc/src/special_elements.dart'; import 'package:package_config/discovery.dart' as package_config; import 'package:path/path.dart' as path; -import 'package:quiver/iterables.dart' as quiver; /// Everything you need to instantiate a PackageGraph object for documenting. abstract class PackageBuilder { diff --git a/lib/src/quiver.dart b/lib/src/quiver.dart new file mode 100644 index 0000000000..dd36843303 --- /dev/null +++ b/lib/src/quiver.dart @@ -0,0 +1,42 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// Methods in-lined from package:quiver. + +// From lib/iterables.dart: + +/// Returns the concatenation of the input iterables. +/// +/// The returned iterable is a lazily-evaluated view on the input iterables. +Iterable concat(Iterable> iterables) => + iterables.expand((x) => x); + +// From lib/src/core/hash.dart: + +/// Generates a hash code for two objects. +int hash2(Object a, Object b) => + _finish(_combine(_combine(0, a.hashCode), b.hashCode)); + +/// Generates a hash code for three objects. +int hash3(Object a, Object b, Object c) => _finish( + _combine(_combine(_combine(0, a.hashCode), b.hashCode), c.hashCode)); + +/// Generates a hash code for four objects. +int hash4(Object a, Object b, Object c, Object d) => _finish(_combine( + _combine(_combine(_combine(0, a.hashCode), b.hashCode), c.hashCode), + d.hashCode)); + +// Jenkins hash functions + +int _combine(int hash, int value) { + hash = 0x1fffffff & (hash + value); + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); +} + +int _finish(int hash) { + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); +} diff --git a/lib/src/tuple.dart b/lib/src/tuple.dart index 69d43fb65b..e4e1dfe926 100644 --- a/lib/src/tuple.dart +++ b/lib/src/tuple.dart @@ -5,7 +5,7 @@ // file for details. All rights reserved. Use of this source code is governed // by a BSD-style license that can be found in the LICENSE file. -import 'package:quiver/core.dart'; +import 'package:dartdoc/src/quiver.dart' as quiver; /// Represents a 2-tuple, or pair. class Tuple2 { @@ -26,7 +26,7 @@ class Tuple2 { o is Tuple2 && o.item1 == item1 && o.item2 == item2; @override - int get hashCode => hash2(item1.hashCode, item2.hashCode); + int get hashCode => quiver.hash2(item1.hashCode, item2.hashCode); } /// Represents a 3-tuple, or triple. @@ -51,7 +51,8 @@ class Tuple3 { o is Tuple3 && o.item1 == item1 && o.item2 == item2 && o.item3 == item3; @override - int get hashCode => hash3(item1.hashCode, item2.hashCode, item3.hashCode); + int get hashCode => + quiver.hash3(item1.hashCode, item2.hashCode, item3.hashCode); } /// Represents a 4-tuple, or quadruple. @@ -83,6 +84,6 @@ class Tuple4 { o.item4 == item4; @override - int get hashCode => - hash4(item1.hashCode, item2.hashCode, item3.hashCode, item4.hashCode); + int get hashCode => quiver.hash4( + item1.hashCode, item2.hashCode, item3.hashCode, item4.hashCode); } diff --git a/pubspec.yaml b/pubspec.yaml index 26d37c0347..ecd5684ed0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,10 +7,10 @@ environment: sdk: '>=2.7.0 <3.0.0' dependencies: - analyzer: ^0.39.12 + analyzer: ^0.39.16 args: '>=1.5.0 <2.0.0' collection: ^1.2.0 - cli_util: ^0.1.3+2 + cli_util: '>=0.1.4 <0.3.0' crypto: ^2.0.6 html: '>=0.12.1 <0.15.0' # We don't use http_parser directly; this dep exists to ensure that we get at @@ -24,7 +24,6 @@ dependencies: package_config: '>=0.1.5 <2.0.0' path: ^1.3.0 pub_semver: ^1.3.7 - quiver: ^2.0.0 resource: ^2.1.2 stack_trace: ^1.4.2 yaml: ^2.1.0 @@ -34,7 +33,7 @@ dev_dependencies: build: ^1.3.0 build_runner: ^1.10.0 build_version: ^2.0.1 - coverage: ^0.13.0 + coverage: ^0.14.0 dhttpd: ^3.0.0 glob: ^1.1.5 grinder: ^0.8.2 diff --git a/test/quiver_test.dart b/test/quiver_test.dart new file mode 100644 index 0000000000..4e59f6f6f5 --- /dev/null +++ b/test/quiver_test.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:test/test.dart'; +import 'package:dartdoc/src/quiver.dart'; + +void main() { + group('concat', () { + test('should handle empty input iterables', () { + expect(concat([]), isEmpty); + }); + + test('should handle single input iterables', () { + expect( + concat([ + [1, 2, 3] + ]), + [1, 2, 3]); + }); + + test('should chain multiple input iterables', () { + expect( + concat([ + [1, 2, 3], + [-1, -2, -3] + ]), + [1, 2, 3, -1, -2, -3]); + }); + + test('should throw for null input', () { + expect(() => concat(null), throwsNoSuchMethodError); + }); + + test('should throw if any input is null', () { + expect( + () => concat([ + [1, 2], + null, + [3, 4] + ]).toList(), + throwsNoSuchMethodError); + }); + + test('should reflectchanges in the inputs', () { + var a = [1, 2]; + var b = [4, 5]; + var ab = concat([a, b]); + expect(ab, [1, 2, 4, 5]); + a.add(3); + b.add(6); + expect(ab, [1, 2, 3, 4, 5, 6]); + }); + }); + + group('hash', () { + test('hash2 should return an int', () { + var h = hash2('123', 456); + expect(h, isA()); + }); + + test('hash3 should return an int', () { + var h = hash3('123', 456, true); + expect(h, isA()); + }); + + test('hash4 should return an int', () { + var h = hash4('123', 456, true, []); + expect(h, isA()); + }); + }); +}