From 26b8758045b6dbf4597773c5c9802518f2fe40fb Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Tue, 2 Feb 2021 09:24:42 -0800 Subject: [PATCH 1/8] initial implementation --- lib/src/model/library.dart | 4 +- lib/src/model/model_element.dart | 4 +- lib/src/model/package_builder.dart | 4 +- lib/src/model/typedef.dart | 19 +- pubspec.yaml | 8 + test/end2end/model_special_cases_test.dart | 405 ++++++++++-------- .../analysis_options.yaml | 1 + .../lib/generalized_typedefs.dart | 22 + testing/test_package_experiments/pubspec.yaml | 2 +- 9 files changed, 262 insertions(+), 207 deletions(-) create mode 100644 testing/test_package_experiments/lib/generalized_typedefs.dart diff --git a/lib/src/model/library.dart b/lib/src/model/library.dart index b7d677e6f0..16eff8a60a 100644 --- a/lib/src/model/library.dart +++ b/lib/src/model/library.dart @@ -104,9 +104,9 @@ class Library extends ModelElement with Categorization, TopLevelContainer { compilationUnit.enums, compilationUnit.extensions, compilationUnit.functions, - compilationUnit.functionTypeAliases, compilationUnit.mixins, compilationUnit.topLevelVariables, + compilationUnit.typeAliases, compilationUnit.types, ]); } @@ -493,7 +493,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer { @override List get typedefs { _typedefs ??= _exportedAndLocalElements - .whereType() + .whereType() .map((e) => ModelElement.from(e, this, packageGraph) as Typedef) .toList(growable: false); return _typedefs; diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index 8c8b744b84..65b33c6a8a 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -336,7 +336,7 @@ abstract class ModelElement extends Canonicalization assert(e.enclosingElement.name != ''); return ModelFunctionTypedef(e, library, packageGraph); } - if (e is FunctionTypeAliasElement) { + if (e is TypeAliasElement) { return Typedef(e, library, packageGraph); } if (e is ConstructorElement) { @@ -1004,7 +1004,7 @@ abstract class ModelElement extends Canonicalization _modelType = ElementType.from(element.thisType, library, packageGraph); } else if (element is FunctionTypeAliasElement) { _modelType = - ElementType.from(element.function.type, library, packageGraph); + ElementType.from(element.aliasedType, library, packageGraph); } else if (element is FunctionTypedElement) { _modelType = ElementType.from(element.type, library, packageGraph); } else if (element is ParameterElement) { diff --git a/lib/src/model/package_builder.dart b/lib/src/model/package_builder.dart index da9fd6f6f5..ac233b90bc 100644 --- a/lib/src/model/package_builder.dart +++ b/lib/src/model/package_builder.dart @@ -10,7 +10,9 @@ import 'package:analyzer/dart/analysis/results.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/src/context/builder.dart'; +import 'package:analyzer/src/dart/analysis/session.dart'; import 'package:analyzer/src/dart/sdk/sdk.dart'; +import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/java_io.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; @@ -155,7 +157,7 @@ class PubPackageBuilder implements PackageBuilder { var analysisContext = contextCollection.contextFor(config.inputDir); var session = analysisContext.currentSession; var sourceKind = await session.getSourceKind(filePath); - + print('nonfunction_type_aliases for ${config.inputDir} : ${((session as AnalysisSessionImpl).getDriver().analysisOptions as AnalysisOptionsImpl).experimentStatus.nonfunction_type_aliases}'); // Allow dart source files with inappropriate suffixes (#1897). Those // do not show up as SourceKind.LIBRARY. if (sourceKind != SourceKind.PART) { diff --git a/lib/src/model/typedef.dart b/lib/src/model/typedef.dart index 3be07634b2..3006ef6d4c 100644 --- a/lib/src/model/typedef.dart +++ b/lib/src/model/typedef.dart @@ -10,10 +10,13 @@ import 'package:dartdoc/src/render/typedef_renderer.dart'; class Typedef extends ModelElement with TypeParameters, Categorization implements EnclosedElement { - Typedef(FunctionTypeAliasElement element, Library library, + Typedef(TypeAliasElement element, Library library, PackageGraph packageGraph) : super(element, library, packageGraph, null); + @override + TypeAliasElement get element => super.element; + @override ModelElement get enclosingElement => library; @@ -24,10 +27,7 @@ class Typedef extends ModelElement String get genericParameters => _renderer.renderGenericParameters(this); List get genericTypeParameters { - if (element is FunctionTypeAliasElement) { - return (element as FunctionTypeAliasElement).function.typeParameters; - } - return Iterable.empty(); + return element.typeParameters; } @override @@ -52,15 +52,10 @@ class Typedef extends ModelElement String get linkedReturnType => modelType.createLinkedReturnTypeName(); @override - // TODO(jcollins-g): change to FunctionTypeElementType after analyzer 0.41 - // ignore: unnecessary_overrides - ElementType get modelType => super.modelType; - - FunctionTypeAliasElement get _typedef => - (element as FunctionTypeAliasElement); + FunctionTypeElementType get modelType => super.modelType; @override - List get typeParameters => _typedef.typeParameters.map((f) { + List get typeParameters => element.typeParameters.map((f) { return ModelElement.from(f, library, packageGraph) as TypeParameter; }).toList(); diff --git a/pubspec.yaml b/pubspec.yaml index 5aeb5f617b..53aca6e646 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,3 +40,11 @@ dev_dependencies: executables: dartdoc: null + +dependency_overrides: + analyzer: + path: '/Users/jcollins/dart/sdk/sdk/pkg/analyzer' + _fe_analyzer_shared: + path: '/Users/jcollins/dart/sdk/sdk/pkg/_fe_analyzer_shared' + #meta: + # path: '/Users/jcollins/dart/sdk/sdk/pkg/meta' diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index e6f2114025..b80a242b20 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -81,198 +81,225 @@ void main() { final _nullSafetyExperimentAllowed = VersionRange(min: Version.parse('2.9.0-9.0.dev'), includeMin: true); + final _generalizedTypedefsAllowed = + VersionRange(min: Version.parse('2.12.0-279.0.dev'), includeMin: true); + // Experimental features not yet enabled by default. Move tests out of this // block when the feature is enabled by default. group('Experiments', () { - Library lateFinalWithoutInitializer, - nullSafetyClassMemberDeclarations, - optOutOfNullSafety, - nullableElements; - Class b; - Class c; - - setUpAll(() async { - lateFinalWithoutInitializer = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'late_final_without_initializer'); - nullSafetyClassMemberDeclarations = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'nnbd_class_member_declarations'); - optOutOfNullSafety = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'opt_out_of_nnbd'); - nullableElements = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'nullable_elements'); - b = nullSafetyClassMemberDeclarations.allClasses - .firstWhere((c) => c.name == 'B'); - c = nullSafetyClassMemberDeclarations.allClasses - .firstWhere((c) => c.name == 'C'); - }); - - test('isNullSafety is set correctly for libraries', () { - expect(lateFinalWithoutInitializer.isNullSafety, isTrue); - expect(optOutOfNullSafety.isNullSafety, isFalse); - }); - - test('method parameters with required', () { - var m1 = b.instanceMethods.firstWhere((m) => m.name == 'm1'); - var p1 = m1.allParameters.firstWhere((p) => p.name == 'p1'); - var p2 = m1.allParameters.firstWhere((p) => p.name == 'p2'); - expect(p1.isRequiredNamed, isTrue); - expect(p2.isRequiredNamed, isFalse); - expect(p2.isNamed, isTrue); - - expect( - m1.linkedParamsLines, - equals( - '
  1. int some,
  2. \n' - '
  3. dynamic regular,
  4. \n' - '
  5. covariant dynamic parameters,
  6. \n' - '
  7. {required dynamic p1,
  8. \n' - '
  9. int p2 = 3,
  10. \n' - '
  11. required covariant dynamic p3,
  12. \n' - '
  13. required covariant int p4}
  14. \n' - '
')); - }); - - test('verify no regression on ordinary optionals', () { - var m2 = b.instanceMethods.firstWhere((m) => m.name == 'm2'); - var sometimes = m2.allParameters.firstWhere((p) => p.name == 'sometimes'); - var optionals = m2.allParameters.firstWhere((p) => p.name == 'optionals'); - expect(sometimes.isRequiredNamed, isFalse); - expect(sometimes.isRequiredPositional, isTrue); - expect(sometimes.isOptionalPositional, isFalse); - expect(optionals.isRequiredNamed, isFalse); - expect(optionals.isRequiredPositional, isFalse); - expect(optionals.isOptionalPositional, isTrue); - - expect( - m2.linkedParamsLines, - equals( - '
  1. int sometimes,
  2. \n' - '
  3. dynamic we,
  4. \n' - '
  5. [String have,
  6. \n' - '
  7. double optionals]
  8. \n' - '
')); - }); - - test('anonymous callback parameters are correctly marked as nullable', () { - var m3 = c.instanceMethods.firstWhere((m) => m.name == 'm3'); - var listen = m3.allParameters.firstWhere((p) => p.name == 'listen'); - var onDone = m3.allParameters.firstWhere((p) => p.name == 'onDone'); - expect(listen.isRequiredPositional, isTrue); - expect(onDone.isNamed, isTrue); - - expect( - m3.linkedParamsLines, - equals( - '
  1. void listen(
    1. int t
    2. \n' - '
    \n' - ')?,
  2. \n' - '
  3. {void onDone(
      \n' - ')?}
    1. \n' - '
    ')); - }); - - test('Late final class member test', () { - var c = lateFinalWithoutInitializer.allClasses - .firstWhere((c) => c.name == 'C'); - var a = c.instanceFields.firstWhere((f) => f.name == 'a'); - var b = c.instanceFields.firstWhere((f) => f.name == 'b'); - var cField = c.instanceFields.firstWhere((f) => f.name == 'cField'); - var dField = c.instanceFields.firstWhere((f) => f.name == 'dField'); - - // If Null safety isn't enabled, fields named 'late' come back from the - // analyzer instead of setting up 'isLate'. - expect(c.instanceFields.any((f) => f.name == 'late'), isFalse); - - expect(a.modelType.returnType.name, equals('dynamic')); - expect(a.isLate, isTrue); - expect(a.features, contains('late')); - - expect(b.modelType.returnType.name, equals('int')); - expect(b.isLate, isTrue); - expect(b.features, contains('late')); - - expect(cField.modelType.returnType.name, equals('dynamic')); - expect(cField.isLate, isTrue); - expect(cField.features, contains('late')); - - expect(dField.modelType.returnType.name, equals('double')); - expect(dField.isLate, isTrue); - expect(dField.features, contains('late')); - }); - - test('Late final top level variables', () { - var initializeMe = lateFinalWithoutInitializer.publicProperties - .firstWhere((v) => v.name == 'initializeMe'); - expect(initializeMe.modelType.returnType.name, equals('String')); - expect(initializeMe.isLate, isTrue); - expect(initializeMe.features, contains('late')); - }); - - test('Opt out of Null safety', () { - var notOptedIn = optOutOfNullSafety.publicProperties - .firstWhere((v) => v.name == 'notOptedIn'); - expect(notOptedIn.isNullSafety, isFalse); - expect(notOptedIn.modelType.nullabilitySuffix, isEmpty); - }); - - test('complex nullable elements are detected and rendered correctly', () { - var complexNullableMembers = nullableElements.allClasses - .firstWhere((c) => c.name == 'ComplexNullableMembers'); - var aComplexType = complexNullableMembers.allFields - .firstWhere((f) => f.name == 'aComplexType'); - var aComplexSetterOnlyType = complexNullableMembers.allFields - .firstWhere((f) => f.name == 'aComplexSetterOnlyType'); - expect(complexNullableMembers.isNullSafety, isTrue); - expect( - complexNullableMembers.nameWithGenerics, - equals( - 'ComplexNullableMembers<T extends String?>')); - expect( - aComplexType.linkedReturnType, - equals( - 'Map<T?, String?>')); - expect(aComplexSetterOnlyType.linkedReturnType, equals( - // TODO(jcollins-g): fix wrong span class for setter-only return type (#2226) - 'List<Map<T?, String?>?>')); - }); - - test('simple nullable elements are detected and rendered correctly', () { - var nullableMembers = nullableElements.allClasses - .firstWhere((c) => c.name == 'NullableMembers'); - var initialized = - nullableMembers.allFields.firstWhere((f) => f.name == 'initialized'); - var nullableField = nullableMembers.allFields - .firstWhere((f) => f.name == 'nullableField'); - var methodWithNullables = nullableMembers.publicInstanceMethods - .firstWhere((f) => f.name == 'methodWithNullables'); - var operatorStar = nullableMembers.publicInstanceOperators - .firstWhere((f) => f.name == 'operator *'); - expect(nullableMembers.isNullSafety, isTrue); - expect( - nullableField.linkedReturnType, - equals( - 'Iterable<BigInt>?')); - expect( - methodWithNullables.linkedParams, - equals( - 'String? foo')); - expect(methodWithNullables.linkedReturnType, equals('int?')); - expect( - initialized.linkedReturnType, - equals( - 'Map<String, Map>?')); - expect( - operatorStar.linkedParams, - equals( - 'NullableMembers? nullableOther')); - }); - }, - skip: (!_nullSafetyExperimentAllowed.allows(_platformVersion) && - !_platformVersionString.contains('edge'))); + group('generalized typedefs', () { + Library generalizedTypedefs; + Typedef T0; + + setUpAll(() async { + generalizedTypedefs = (await _testPackageGraphExperiments) + .libraries + .firstWhere((l) => l.name == 'generalized_typedefs'); + T0 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T0'); + }); + + test('basic non-function typedefs work', () { + throw Exception(); + expect(T0.linkedReturnType, equals('something')); + }); + + }, skip: (!_generalizedTypedefsAllowed.allows(_platformVersion))); + + + group('null safety', () { + Library lateFinalWithoutInitializer, + nullSafetyClassMemberDeclarations, + optOutOfNullSafety, + nullableElements; + Class b; + Class c; + + setUpAll(() async { + lateFinalWithoutInitializer = (await _testPackageGraphExperiments) + .libraries + .firstWhere((lib) => lib.name == 'late_final_without_initializer'); + nullSafetyClassMemberDeclarations = (await _testPackageGraphExperiments) + .libraries + .firstWhere((lib) => lib.name == 'nnbd_class_member_declarations'); + optOutOfNullSafety = (await _testPackageGraphExperiments) + .libraries + .firstWhere((lib) => lib.name == 'opt_out_of_nnbd'); + nullableElements = (await _testPackageGraphExperiments) + .libraries + .firstWhere((lib) => lib.name == 'nullable_elements'); + b = nullSafetyClassMemberDeclarations.allClasses + .firstWhere((c) => c.name == 'B'); + c = nullSafetyClassMemberDeclarations.allClasses + .firstWhere((c) => c.name == 'C'); + }); + + test('isNullSafety is set correctly for libraries', () { + expect(lateFinalWithoutInitializer.isNullSafety, isTrue); + expect(optOutOfNullSafety.isNullSafety, isFalse); + }); + + test('method parameters with required', () { + var m1 = b.instanceMethods.firstWhere((m) => m.name == 'm1'); + var p1 = m1.allParameters.firstWhere((p) => p.name == 'p1'); + var p2 = m1.allParameters.firstWhere((p) => p.name == 'p2'); + expect(p1.isRequiredNamed, isTrue); + expect(p2.isRequiredNamed, isFalse); + expect(p2.isNamed, isTrue); + + expect( + m1.linkedParamsLines, + equals( + '
    1. int some,
    2. \n' + '
    3. dynamic regular,
    4. \n' + '
    5. covariant dynamic parameters,
    6. \n' + '
    7. {required dynamic p1,
    8. \n' + '
    9. int p2 = 3,
    10. \n' + '
    11. required covariant dynamic p3,
    12. \n' + '
    13. required covariant int p4}
    14. \n' + '
    ')); + }); + + test('verify no regression on ordinary optionals', () { + var m2 = b.instanceMethods.firstWhere((m) => m.name == 'm2'); + var sometimes = + m2.allParameters.firstWhere((p) => p.name == 'sometimes'); + var optionals = + m2.allParameters.firstWhere((p) => p.name == 'optionals'); + expect(sometimes.isRequiredNamed, isFalse); + expect(sometimes.isRequiredPositional, isTrue); + expect(sometimes.isOptionalPositional, isFalse); + expect(optionals.isRequiredNamed, isFalse); + expect(optionals.isRequiredPositional, isFalse); + expect(optionals.isOptionalPositional, isTrue); + + expect( + m2.linkedParamsLines, + equals( + '
    1. int sometimes,
    2. \n' + '
    3. dynamic we,
    4. \n' + '
    5. [String have,
    6. \n' + '
    7. double optionals]
    8. \n' + '
    ')); + }); + + test('anonymous callback parameters are correctly marked as nullable', + () { + var m3 = c.instanceMethods.firstWhere((m) => m.name == 'm3'); + var listen = m3.allParameters.firstWhere((p) => p.name == 'listen'); + var onDone = m3.allParameters.firstWhere((p) => p.name == 'onDone'); + expect(listen.isRequiredPositional, isTrue); + expect(onDone.isNamed, isTrue); + + expect( + m3.linkedParamsLines, + equals( + '
    1. void listen(
      1. int t
      2. \n' + '
      \n' + ')?,
    2. \n' + '
    3. {void onDone(
        \n' + ')?}
      1. \n' + '
      ')); + }); + + test('Late final class member test', () { + var c = lateFinalWithoutInitializer.allClasses + .firstWhere((c) => c.name == 'C'); + var a = c.instanceFields.firstWhere((f) => f.name == 'a'); + var b = c.instanceFields.firstWhere((f) => f.name == 'b'); + var cField = c.instanceFields.firstWhere((f) => f.name == 'cField'); + var dField = c.instanceFields.firstWhere((f) => f.name == 'dField'); + + // If Null safety isn't enabled, fields named 'late' come back from the + // analyzer instead of setting up 'isLate'. + expect(c.instanceFields.any((f) => f.name == 'late'), isFalse); + + expect(a.modelType.returnType.name, equals('dynamic')); + expect(a.isLate, isTrue); + expect(a.features, contains('late')); + + expect(b.modelType.returnType.name, equals('int')); + expect(b.isLate, isTrue); + expect(b.features, contains('late')); + + expect(cField.modelType.returnType.name, equals('dynamic')); + expect(cField.isLate, isTrue); + expect(cField.features, contains('late')); + + expect(dField.modelType.returnType.name, equals('double')); + expect(dField.isLate, isTrue); + expect(dField.features, contains('late')); + }); + + test('Late final top level variables', () { + var initializeMe = lateFinalWithoutInitializer.publicProperties + .firstWhere((v) => v.name == 'initializeMe'); + expect(initializeMe.modelType.returnType.name, equals('String')); + expect(initializeMe.isLate, isTrue); + expect(initializeMe.features, contains('late')); + }); + + test('Opt out of Null safety', () { + var notOptedIn = optOutOfNullSafety.publicProperties + .firstWhere((v) => v.name == 'notOptedIn'); + expect(notOptedIn.isNullSafety, isFalse); + expect(notOptedIn.modelType.nullabilitySuffix, isEmpty); + }); + + test('complex nullable elements are detected and rendered correctly', () { + var complexNullableMembers = nullableElements.allClasses + .firstWhere((c) => c.name == 'ComplexNullableMembers'); + var aComplexType = complexNullableMembers.allFields + .firstWhere((f) => f.name == 'aComplexType'); + var aComplexSetterOnlyType = complexNullableMembers.allFields + .firstWhere((f) => f.name == 'aComplexSetterOnlyType'); + expect(complexNullableMembers.isNullSafety, isTrue); + expect( + complexNullableMembers.nameWithGenerics, + equals( + 'ComplexNullableMembers<T extends String?>')); + expect( + aComplexType.linkedReturnType, + equals( + 'Map<T?, String?>')); + expect(aComplexSetterOnlyType.linkedReturnType, equals( + // TODO(jcollins-g): fix wrong span class for setter-only return type (#2226) + 'List<Map<T?, String?>?>')); + }); + + test('simple nullable elements are detected and rendered correctly', () { + var nullableMembers = nullableElements.allClasses + .firstWhere((c) => c.name == 'NullableMembers'); + var initialized = nullableMembers.allFields + .firstWhere((f) => f.name == 'initialized'); + var nullableField = nullableMembers.allFields + .firstWhere((f) => f.name == 'nullableField'); + var methodWithNullables = nullableMembers.publicInstanceMethods + .firstWhere((f) => f.name == 'methodWithNullables'); + var operatorStar = nullableMembers.publicInstanceOperators + .firstWhere((f) => f.name == 'operator *'); + expect(nullableMembers.isNullSafety, isTrue); + expect( + nullableField.linkedReturnType, + equals( + 'Iterable<BigInt>?')); + expect( + methodWithNullables.linkedParams, + equals( + 'String? foo')); + expect(methodWithNullables.linkedReturnType, equals('int?')); + expect( + initialized.linkedReturnType, + equals( + 'Map<String, Map>?')); + expect( + operatorStar.linkedParams, + equals( + 'NullableMembers? nullableOther')); + }); + }, + skip: (!_nullSafetyExperimentAllowed.allows(_platformVersion) && + !_platformVersionString.contains('edge'))); + }); group('HTML Injection when allowed', () { Class htmlInjection; diff --git a/testing/test_package_experiments/analysis_options.yaml b/testing/test_package_experiments/analysis_options.yaml index fa5fdeb9eb..5d00c3a21e 100644 --- a/testing/test_package_experiments/analysis_options.yaml +++ b/testing/test_package_experiments/analysis_options.yaml @@ -2,3 +2,4 @@ analyzer: # enable for analysis on test package sources. enable-experiment: - non-nullable + - nonfunction-type-aliases diff --git a/testing/test_package_experiments/lib/generalized_typedefs.dart b/testing/test_package_experiments/lib/generalized_typedefs.dart new file mode 100644 index 0000000000..c8a10ea5ec --- /dev/null +++ b/testing/test_package_experiments/lib/generalized_typedefs.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2021, 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. + +/// This library validates that dartdoc will not crash on generalized +/// typedef syntax, and produce correct results. +library generalized_typedefs; + +typedef T0 = void; +typedef T1 = Function; +typedef T2 = List; +typedef T3 = Map; +typedef T4 = void Function(); +typedef T5 = X Function(X, {X name}); +typedef T6 = X Function(Y, [Map]); +typedef T7> = X Function(Y, [Map]); + +void main() { + // ignore:unused_local_variable + var ensure_usage = [T0, T1, T2, T3, T4, T5, T6, T7]; + print('hi'); +} diff --git a/testing/test_package_experiments/pubspec.yaml b/testing/test_package_experiments/pubspec.yaml index c0a9b33338..7cbe5c3a49 100644 --- a/testing/test_package_experiments/pubspec.yaml +++ b/testing/test_package_experiments/pubspec.yaml @@ -1,5 +1,5 @@ name: test_package_experiments version: 0.0.1 environment: - sdk: '>=2.10.0-0 <3.0.0' + sdk: '>=2.12.0-0 <3.0.0' description: Experimental flags are tested here. From 75aef94b98c04755fb3bae7cb00928b016fe6214 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Thu, 4 Feb 2021 13:36:50 -0800 Subject: [PATCH 2/8] getting somewhere. mostly works now and no regressions. --- lib/src/model/model_element.dart | 6 ++++- lib/src/model/typedef.dart | 29 ++++++++++++++++----- lib/templates/html/_callable.html | 5 ++-- lib/templates/html/_callable_multiline.html | 6 +++++ lib/templates/html/library.html | 4 +-- pubspec.yaml | 7 +++++ test/end2end/model_test.dart | 2 +- 7 files changed, 47 insertions(+), 12 deletions(-) diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index 65b33c6a8a..b383e796e9 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -9,6 +9,7 @@ import 'dart:collection' show UnmodifiableListView; import 'dart:convert'; import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart' show FunctionType; import 'package:analyzer/source/line_info.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/member.dart' @@ -337,6 +338,9 @@ abstract class ModelElement extends Canonicalization return ModelFunctionTypedef(e, library, packageGraph); } if (e is TypeAliasElement) { + if (e.aliasedType is FunctionType) { + return FunctionTypedef(e, library, packageGraph); + } return Typedef(e, library, packageGraph); } if (e is ConstructorElement) { @@ -1002,7 +1006,7 @@ abstract class ModelElement extends Canonicalization } } else if (element is ClassElement) { _modelType = ElementType.from(element.thisType, library, packageGraph); - } else if (element is FunctionTypeAliasElement) { + } else if (element is TypeAliasElement) { _modelType = ElementType.from(element.aliasedType, library, packageGraph); } else if (element is FunctionTypedElement) { diff --git a/lib/src/model/typedef.dart b/lib/src/model/typedef.dart index 3006ef6d4c..ca312598b4 100644 --- a/lib/src/model/typedef.dart +++ b/lib/src/model/typedef.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/render/typedef_renderer.dart'; @@ -14,6 +15,8 @@ class Typedef extends ModelElement PackageGraph packageGraph) : super(element, library, packageGraph, null); + DartType get aliasedType => element.aliasedType; + @override TypeAliasElement get element => super.element; @@ -26,9 +29,7 @@ class Typedef extends ModelElement @override String get genericParameters => _renderer.renderGenericParameters(this); - List get genericTypeParameters { - return element.typeParameters; - } + List get genericTypeParameters => element.typeParameters; @override String get filePath => '${library.dirName}/$fileName'; @@ -51,9 +52,6 @@ class Typedef extends ModelElement String get linkedReturnType => modelType.createLinkedReturnTypeName(); - @override - FunctionTypeElementType get modelType => super.modelType; - @override List get typeParameters => element.typeParameters.map((f) { return ModelElement.from(f, library, packageGraph) as TypeParameter; @@ -61,3 +59,22 @@ class Typedef extends ModelElement TypedefRenderer get _renderer => packageGraph.rendererFactory.typedefRenderer; } + +/// A typedef referring to a function type. +class FunctionTypedef extends Typedef { + FunctionTypedef(TypeAliasElement element, Library library, + PackageGraph packageGraph) + : super(element, library, packageGraph); + + @override + FunctionType get aliasedType => super.aliasedType; + + @override + List get genericTypeParameters { + var aliasedTypeElement = aliasedType.element; + if (aliasedTypeElement is FunctionTypedElement) { + return aliasedTypeElement.typeParameters; + } + return aliasedType.typeFormals; + } +} \ No newline at end of file diff --git a/lib/templates/html/_callable.html b/lib/templates/html/_callable.html index 7fb911b573..1988fbb5a7 100644 --- a/lib/templates/html/_callable.html +++ b/lib/templates/html/_callable.html @@ -1,5 +1,6 @@ -
      - {{{linkedName}}}{{{linkedGenericParameters}}}({{{ linkedParamsNoMetadata }}}) +
      + {{{linkedName}}}{{{linkedGenericParameters}}}{{#canHaveParameters}}({{{ linkedParamsNoMetadata }}}){{/canHaveParameters}} + {{^canHaveParameters}} = {{/canHaveParameters}} → {{{ linkedReturnType }}} {{>categorization}} diff --git a/lib/templates/html/_callable_multiline.html b/lib/templates/html/_callable_multiline.html index 4d0bce92a5..935f581b95 100644 --- a/lib/templates/html/_callable_multiline.html +++ b/lib/templates/html/_callable_multiline.html @@ -7,5 +7,11 @@ {{/hasAnnotations}} +{{#canHaveParameters}} + {{{ linkedReturnType }}} {{>name_summary}}{{{genericParameters}}}({{#hasParameters}}{{{linkedParamsLines}}}{{/hasParameters}}) +{{/canHaveParameters}} +{{^canHaveParameters}} +{{>name_summary}}{{{genericParameters}}} = {{{linkedReturnType}}} +{{/canHaveParameters}} diff --git a/lib/templates/html/library.html b/lib/templates/html/library.html index 10e1121781..5d6eea419b 100644 --- a/lib/templates/html/library.html +++ b/lib/templates/html/library.html @@ -103,9 +103,9 @@

      Enums

      Typedefs

      -
      +
      {{#library.publicTypedefsSorted}} - {{>callable}} + {{>callable}} {{/library.publicTypedefsSorted}}
      diff --git a/pubspec.yaml b/pubspec.yaml index 53aca6e646..bf207a4fe7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,6 +42,13 @@ executables: dartdoc: null dependency_overrides: + args: ^2.0.0-nullsafety.0 + cli_util: ^0.3.0-nullsafety.0 + crypto: ^3.0.0-nullsafety.0 + glob: ^2.0.0-nullsafety.0 + package_config: ^2.0.0-nullsafety.0 + pub_semver: ^2.0.0-nullsafety.0 + yaml: ^3.0.0-nullsafety.0 analyzer: path: '/Users/jcollins/dart/sdk/sdk/pkg/analyzer' _fe_analyzer_shared: diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index 92d51c1f48..6dbb6ca5e6 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -3961,4 +3961,4 @@ class StringName extends Nameable { @override String toString() => name; -} +} \ No newline at end of file From 4a9e009a1e63eedacf63241ab05396eb4120bf90 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Thu, 4 Feb 2021 15:44:46 -0800 Subject: [PATCH 3/8] refactor to extract function typedefs --- lib/src/element_type.dart | 2 +- lib/src/generator/templates.dart | 4 ++++ lib/src/model/getter_setter_combo.dart | 2 +- lib/src/model/model_element.dart | 10 ++++++---- lib/src/model/typedef.dart | 6 ++++-- lib/templates/html/_callable.html | 5 ++--- lib/templates/html/_callable_multiline.html | 5 ----- lib/templates/html/_name_summary.html | 2 +- lib/templates/html/_type.html | 11 +++++++++++ lib/templates/html/_type_multiline.html | 10 ++++++++++ lib/templates/html/_typedef.html | 6 ++++++ lib/templates/html/_typedef_multiline.html | 6 ++++++ lib/templates/html/category.html | 2 +- lib/templates/html/library.html | 2 +- lib/templates/html/typedef.html | 2 +- test/end2end/model_test.dart | 2 +- test/html_generator_test.dart | 4 ++++ 17 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 lib/templates/html/_type.html create mode 100644 lib/templates/html/_type_multiline.html create mode 100644 lib/templates/html/_typedef.html create mode 100644 lib/templates/html/_typedef_multiline.html diff --git a/lib/src/element_type.dart b/lib/src/element_type.dart index e7dab1d650..7bb6bd7cdd 100644 --- a/lib/src/element_type.dart +++ b/lib/src/element_type.dart @@ -280,7 +280,7 @@ abstract class DefinedElementType extends ElementType { @override List get parameters => - element.canHaveParameters ? element.parameters : []; + element.isCallable ? element.parameters : []; ModelElement get returnElement => element; ElementType _returnType; diff --git a/lib/src/generator/templates.dart b/lib/src/generator/templates.dart index 1e53a5f6e2..19753b6c47 100644 --- a/lib/src/generator/templates.dart +++ b/lib/src/generator/templates.dart @@ -41,6 +41,10 @@ const _partials_html = [ 'source_code', 'source_link', 'sidebar_for_library', + 'type', + 'type_multiline', + 'typedef', + 'typedef_multiline', 'accessor_getter', 'accessor_setter', ]; diff --git a/lib/src/model/getter_setter_combo.dart b/lib/src/model/getter_setter_combo.dart index d1cba5ca3b..9bdae381b0 100644 --- a/lib/src/model/getter_setter_combo.dart +++ b/lib/src/model/getter_setter_combo.dart @@ -193,7 +193,7 @@ mixin GetterSetterCombo on ModelElement { } @override - bool get canHaveParameters => hasSetter; + bool get isCallable => hasSetter; @override List get parameters => setter.parameters; diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index b383e796e9..663dc1c109 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -338,6 +338,9 @@ abstract class ModelElement extends Canonicalization return ModelFunctionTypedef(e, library, packageGraph); } if (e is TypeAliasElement) { + if (e.name == 'T5') { + print('hello'); + } if (e.aliasedType is FunctionType) { return FunctionTypedef(e, library, packageGraph); } @@ -550,8 +553,7 @@ abstract class ModelElement extends Canonicalization return allFeatures.join(', '); } - bool get canHaveParameters => - element is ExecutableElement || + bool get isCallable => element is FunctionTypedElement || element is FunctionTypeAliasElement; @@ -1058,7 +1060,7 @@ abstract class ModelElement extends Canonicalization (this as GetterSetterCombo).setter != null) { newParameters.addAll((this as GetterSetterCombo).setter.parameters); } else { - if (canHaveParameters) newParameters.addAll(parameters); + if (isCallable) newParameters.addAll(parameters); } while (newParameters.isNotEmpty) { recursedParameters.addAll(newParameters); @@ -1078,7 +1080,7 @@ abstract class ModelElement extends Canonicalization path.Context get pathContext => packageGraph.resourceProvider.pathContext; List get parameters { - if (!canHaveParameters) { + if (!isCallable) { throw StateError('$element cannot have parameters'); } diff --git a/lib/src/model/typedef.dart b/lib/src/model/typedef.dart index ca312598b4..ca9757f0c8 100644 --- a/lib/src/model/typedef.dart +++ b/lib/src/model/typedef.dart @@ -4,7 +4,6 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; -import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/render/typedef_renderer.dart'; @@ -75,6 +74,9 @@ class FunctionTypedef extends Typedef { if (aliasedTypeElement is FunctionTypedElement) { return aliasedTypeElement.typeParameters; } - return aliasedType.typeFormals; + if (aliasedType.typeFormals.isNotEmpty == true) { + return aliasedType.typeFormals; + } + return super.genericTypeParameters; } } \ No newline at end of file diff --git a/lib/templates/html/_callable.html b/lib/templates/html/_callable.html index 1988fbb5a7..7fb911b573 100644 --- a/lib/templates/html/_callable.html +++ b/lib/templates/html/_callable.html @@ -1,6 +1,5 @@ -
      - {{{linkedName}}}{{{linkedGenericParameters}}}{{#canHaveParameters}}({{{ linkedParamsNoMetadata }}}){{/canHaveParameters}} - {{^canHaveParameters}} = {{/canHaveParameters}} +
      + {{{linkedName}}}{{{linkedGenericParameters}}}({{{ linkedParamsNoMetadata }}}) → {{{ linkedReturnType }}} {{>categorization}} diff --git a/lib/templates/html/_callable_multiline.html b/lib/templates/html/_callable_multiline.html index 935f581b95..ab0fa11769 100644 --- a/lib/templates/html/_callable_multiline.html +++ b/lib/templates/html/_callable_multiline.html @@ -7,11 +7,6 @@ {{/hasAnnotations}} -{{#canHaveParameters}} {{{ linkedReturnType }}} {{>name_summary}}{{{genericParameters}}}({{#hasParameters}}{{{linkedParamsLines}}}{{/hasParameters}}) -{{/canHaveParameters}} -{{^canHaveParameters}} -{{>name_summary}}{{{genericParameters}}} = {{{linkedReturnType}}} -{{/canHaveParameters}} diff --git a/lib/templates/html/_name_summary.html b/lib/templates/html/_name_summary.html index 73fca35cbb..2f2d11e526 100644 --- a/lib/templates/html/_name_summary.html +++ b/lib/templates/html/_name_summary.html @@ -1 +1 @@ -{{#isConst}}const {{/isConst}}{{name}} +{{#isConst}}const {{/isConst}}{{name}} \ No newline at end of file diff --git a/lib/templates/html/_type.html b/lib/templates/html/_type.html new file mode 100644 index 0000000000..7ac5632cfc --- /dev/null +++ b/lib/templates/html/_type.html @@ -0,0 +1,11 @@ +
      + {{{linkedName}}}{{{linkedGenericParameters}}} + = + {{{ linkedReturnType }}} + + {{>categorization}} +
      + + {{{ oneLineDoc }}} {{{ extendedDocLink }}} + {{>features}} + diff --git a/lib/templates/html/_type_multiline.html b/lib/templates/html/_type_multiline.html new file mode 100644 index 0000000000..71b80368df --- /dev/null +++ b/lib/templates/html/_type_multiline.html @@ -0,0 +1,10 @@ +{{#hasAnnotations}} +
      +
        + {{#annotations}} +
      1. {{{.}}}
      2. + {{/annotations}} +
      +
      +{{/hasAnnotations}} +{{>name_summary}}{{{genericParameters}}} = {{{linkedReturnType}}} diff --git a/lib/templates/html/_typedef.html b/lib/templates/html/_typedef.html new file mode 100644 index 0000000000..7d2453299f --- /dev/null +++ b/lib/templates/html/_typedef.html @@ -0,0 +1,6 @@ +{{#isCallable}} + {{>callable}} +{{/isCallable}} +{{^isCallable}} + {{>type}} +{{/isCallable}} diff --git a/lib/templates/html/_typedef_multiline.html b/lib/templates/html/_typedef_multiline.html new file mode 100644 index 0000000000..c1139581c3 --- /dev/null +++ b/lib/templates/html/_typedef_multiline.html @@ -0,0 +1,6 @@ +{{#isCallable}} + {{>callable_multiline}} +{{/isCallable}} +{{^isCallable}} + {{>type_multiline}} +{{/isCallable}} diff --git a/lib/templates/html/category.html b/lib/templates/html/category.html index 9a371f442d..929dd7f0bc 100644 --- a/lib/templates/html/category.html +++ b/lib/templates/html/category.html @@ -101,7 +101,7 @@

      Typedefs

      {{#publicTypedefsSorted}} - {{>callable}} + {{>typedef}} {{/publicTypedefsSorted}}
      diff --git a/lib/templates/html/library.html b/lib/templates/html/library.html index 5d6eea419b..b683d187b0 100644 --- a/lib/templates/html/library.html +++ b/lib/templates/html/library.html @@ -105,7 +105,7 @@

      Typedefs

      {{#library.publicTypedefsSorted}} - {{>callable}} + {{>typedef}} {{/library.publicTypedefsSorted}}
      diff --git a/lib/templates/html/typedef.html b/lib/templates/html/typedef.html index 52af2ed89f..37cc5de239 100644 --- a/lib/templates/html/typedef.html +++ b/lib/templates/html/typedef.html @@ -13,7 +13,7 @@
      {{parent.name}} {{parent.kind}}
      {{#typeDef}} - {{>callable_multiline}} + {{>typedef_multiline}} {{/typeDef}}
      diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index 6dbb6ca5e6..982c02240c 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -2562,7 +2562,7 @@ String topLevelFunction(int param1, bool param2, Cool coolBeans, }); test('can have params', () { - expect(isGreaterThan.canHaveParameters, isTrue); + expect(isGreaterThan.isCallable, isTrue); }); test('has parameters', () { diff --git a/test/html_generator_test.dart b/test/html_generator_test.dart index 969ca43819..e8559b9af5 100644 --- a/test/html_generator_test.dart +++ b/test/html_generator_test.dart @@ -63,6 +63,10 @@ void main() { '_sidebar_for_library', '_source_code', '_source_link', + '_type', + '_typedef', + '_type_multiline', + '_typedef_multiline', '404error', 'category', 'class', From 7b0803cd7ff6135078bbfd667d53aaa164b1c1c7 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Fri, 5 Feb 2021 11:00:08 -0800 Subject: [PATCH 4/8] cleanup and tests pass --- lib/src/model/package_builder.dart | 2 +- test/end2end/model_special_cases_test.dart | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/src/model/package_builder.dart b/lib/src/model/package_builder.dart index aac49e6e21..d266a58a9f 100644 --- a/lib/src/model/package_builder.dart +++ b/lib/src/model/package_builder.dart @@ -157,7 +157,7 @@ class PubPackageBuilder implements PackageBuilder { var analysisContext = contextCollection.contextFor(config.inputDir); var session = analysisContext.currentSession; var sourceKind = await session.getSourceKind(filePath); - print('nonfunction_type_aliases for ${config.inputDir} : ${((session as AnalysisSessionImpl).getDriver().analysisOptions as AnalysisOptionsImpl).experimentStatus.nonfunction_type_aliases}'); + // Allow dart source files with inappropriate suffixes (#1897). Those // do not show up as SourceKind.LIBRARY. if (sourceKind != SourceKind.PART) { diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index e4205b51b4..f31f848635 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -99,8 +99,7 @@ void main() { }); test('basic non-function typedefs work', () { - throw Exception(); - expect(T0.linkedReturnType, equals('something')); + expect(T0.linkedReturnType, equals('dynamic')); }); }, skip: (!_generalizedTypedefsAllowed.allows(_platformVersion))); From cf15fdd64724d2301f1ab23482ad15ec03ae04d4 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Mon, 8 Feb 2021 10:22:56 -0800 Subject: [PATCH 5/8] more tweaks --- lib/src/model/model_element.dart | 3 --- lib/src/model/package_builder.dart | 4 +-- test/end2end/model_special_cases_test.dart | 25 ++++++++++++++++--- testing/test_package_experiments/pubspec.yaml | 2 +- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index 663dc1c109..f08d5ecafa 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -338,9 +338,6 @@ abstract class ModelElement extends Canonicalization return ModelFunctionTypedef(e, library, packageGraph); } if (e is TypeAliasElement) { - if (e.name == 'T5') { - print('hello'); - } if (e.aliasedType is FunctionType) { return FunctionTypedef(e, library, packageGraph); } diff --git a/lib/src/model/package_builder.dart b/lib/src/model/package_builder.dart index d266a58a9f..a24dcaf161 100644 --- a/lib/src/model/package_builder.dart +++ b/lib/src/model/package_builder.dart @@ -10,9 +10,7 @@ import 'package:analyzer/dart/analysis/results.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/src/context/builder.dart'; -import 'package:analyzer/src/dart/analysis/session.dart'; import 'package:analyzer/src/dart/sdk/sdk.dart'; -import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/java_io.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; @@ -157,7 +155,7 @@ class PubPackageBuilder implements PackageBuilder { var analysisContext = contextCollection.contextFor(config.inputDir); var session = analysisContext.currentSession; var sourceKind = await session.getSourceKind(filePath); - + // Allow dart source files with inappropriate suffixes (#1897). Those // do not show up as SourceKind.LIBRARY. if (sourceKind != SourceKind.PART) { diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index f31f848635..2810260a62 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -32,7 +32,7 @@ Future get _testPackageGraphExperiments => PhysicalPackageConfigProvider(), additionalArguments: [ '--enable-experiment', - 'non-nullable', + 'non-nullable,nonfunction-type-aliases', '--no-link-to-remote' ])); @@ -89,17 +89,36 @@ void main() { group('Experiments', () { group('generalized typedefs', () { Library generalizedTypedefs; - Typedef T0; + Typedef T0, T1, T2, T3, T4, T5, T6, T7; setUpAll(() async { generalizedTypedefs = (await _testPackageGraphExperiments) .libraries .firstWhere((l) => l.name == 'generalized_typedefs'); T0 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T0'); + T1 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T1'); + T2 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T2'); + T3 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T3'); + T4 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T4'); + T5 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T5'); + T6 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T6'); + T7 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T7'); }); + void expectTypedefs(Typedef t, String modelTypeToString, String genericParameters) { + expect(t.modelType.toString(), equals(modelTypeToString)); + expect(t.genericParameters, equals(genericParameters)); + } + test('basic non-function typedefs work', () { - expect(T0.linkedReturnType, equals('dynamic')); + expectTypedefs(T0, 'void', ''); + expectTypedefs(T1, 'Function', ''); + expectTypedefs(T2, 'List', ''); + expectTypedefs(T3, '', ''); + expectTypedefs(T4, '', ''); + expectTypedefs(T5, '', ''); + expectTypedefs(T6, '', ''); + expectTypedefs(T7, '', ''); }); }, skip: (!_generalizedTypedefsAllowed.allows(_platformVersion))); diff --git a/testing/test_package_experiments/pubspec.yaml b/testing/test_package_experiments/pubspec.yaml index 7cbe5c3a49..32c96d812b 100644 --- a/testing/test_package_experiments/pubspec.yaml +++ b/testing/test_package_experiments/pubspec.yaml @@ -1,5 +1,5 @@ name: test_package_experiments version: 0.0.1 environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.13.0-0 <3.0.0' description: Experimental flags are tested here. From 20ba327c94f3fc36e31b3307d28f3a414bb4179f Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Thu, 4 Mar 2021 10:58:36 -0800 Subject: [PATCH 6/8] merge leftover --- test/end2end/model_special_cases_test.dart | 202 +-------------------- 1 file changed, 6 insertions(+), 196 deletions(-) diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index b70b36c95d..a44acb287d 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -16,10 +16,14 @@ import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/package_config_provider.dart'; import 'package:dartdoc/src/package_meta.dart'; import 'package:dartdoc/src/special_elements.dart'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import '../src/utils.dart' as utils; +final String _platformVersionString = Platform.version.split(' ').first; +final Version _platformVersion = Version.parse(_platformVersionString); + final _testPackageGraphExperimentsMemo = AsyncMemoizer(); Future get _testPackageGraphExperiments => _testPackageGraphExperimentsMemo.runOnce(() => utils.bootBasicPackage( @@ -70,6 +74,8 @@ void main() { exit(1); } + final _generalizedTypedefsAllowed = + VersionRange(min: Version.parse('2.13.0-0'), includeMin: true); // Experimental features not yet enabled by default. Move tests out of this // block when the feature is enabled by default. group('Experiments', () { @@ -106,203 +112,7 @@ void main() { expectTypedefs(T6, '', ''); expectTypedefs(T7, '', ''); }); - }, skip: (!_generalizedTypedefsAllowed.allows(_platformVersion))); - - - group('null safety', () { - Library lateFinalWithoutInitializer, - nullSafetyClassMemberDeclarations, - optOutOfNullSafety, - nullableElements; - Class b; - Class c; - - setUpAll(() async { - lateFinalWithoutInitializer = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'late_final_without_initializer'); - nullSafetyClassMemberDeclarations = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'nnbd_class_member_declarations'); - optOutOfNullSafety = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'opt_out_of_nnbd'); - nullableElements = (await _testPackageGraphExperiments) - .libraries - .firstWhere((lib) => lib.name == 'nullable_elements'); - b = nullSafetyClassMemberDeclarations.allClasses - .firstWhere((c) => c.name == 'B'); - c = nullSafetyClassMemberDeclarations.allClasses - .firstWhere((c) => c.name == 'C'); - }); - - test('isNullSafety is set correctly for libraries', () { - expect(lateFinalWithoutInitializer.isNullSafety, isTrue); - expect(optOutOfNullSafety.isNullSafety, isFalse); - }); - - test('method parameters with required', () { - var m1 = b.instanceMethods.firstWhere((m) => m.name == 'm1'); - var p1 = m1.allParameters.firstWhere((p) => p.name == 'p1'); - var p2 = m1.allParameters.firstWhere((p) => p.name == 'p2'); - expect(p1.isRequiredNamed, isTrue); - expect(p2.isRequiredNamed, isFalse); - expect(p2.isNamed, isTrue); - - expect( - m1.linkedParamsLines, - equals( - '
      1. int some,
      2. \n' - '
      3. dynamic regular,
      4. \n' - '
      5. covariant dynamic parameters,
      6. \n' - '
      7. {required dynamic p1,
      8. \n' - '
      9. int p2 = 3,
      10. \n' - '
      11. required covariant dynamic p3,
      12. \n' - '
      13. required covariant int p4}
      14. \n' - '
      ')); - }); - - test('verify no regression on ordinary optionals', () { - var m2 = b.instanceMethods.firstWhere((m) => m.name == 'm2'); - var sometimes = - m2.allParameters.firstWhere((p) => p.name == 'sometimes'); - var optionals = - m2.allParameters.firstWhere((p) => p.name == 'optionals'); - expect(sometimes.isRequiredNamed, isFalse); - expect(sometimes.isRequiredPositional, isTrue); - expect(sometimes.isOptionalPositional, isFalse); - expect(optionals.isRequiredNamed, isFalse); - expect(optionals.isRequiredPositional, isFalse); - expect(optionals.isOptionalPositional, isTrue); - - expect( - m2.linkedParamsLines, - equals( - '
      1. int sometimes,
      2. \n' - '
      3. dynamic we,
      4. \n' - '
      5. [String have,
      6. \n' - '
      7. double optionals]
      8. \n' - '
      ')); - }); - - test('anonymous callback parameters are correctly marked as nullable', - () { - var m3 = c.instanceMethods.firstWhere((m) => m.name == 'm3'); - var listen = m3.allParameters.firstWhere((p) => p.name == 'listen'); - var onDone = m3.allParameters.firstWhere((p) => p.name == 'onDone'); - expect(listen.isRequiredPositional, isTrue); - expect(onDone.isNamed, isTrue); - - expect( - m3.linkedParamsLines, - equals( - '
      1. void listen(
        1. int t
        2. \n' - '
        \n' - ')?,
      2. \n' - '
      3. {void onDone(
          \n' - ')?}
        1. \n' - '
        ')); - }); - - test('Late final class member test', () { - var c = lateFinalWithoutInitializer.allClasses - .firstWhere((c) => c.name == 'C'); - var a = c.instanceFields.firstWhere((f) => f.name == 'a'); - var b = c.instanceFields.firstWhere((f) => f.name == 'b'); - var cField = c.instanceFields.firstWhere((f) => f.name == 'cField'); - var dField = c.instanceFields.firstWhere((f) => f.name == 'dField'); - - // If Null safety isn't enabled, fields named 'late' come back from the - // analyzer instead of setting up 'isLate'. - expect(c.instanceFields.any((f) => f.name == 'late'), isFalse); - - expect(a.modelType.returnType.name, equals('dynamic')); - expect(a.isLate, isTrue); - expect(a.features, contains('late')); - - expect(b.modelType.returnType.name, equals('int')); - expect(b.isLate, isTrue); - expect(b.features, contains('late')); - - expect(cField.modelType.returnType.name, equals('dynamic')); - expect(cField.isLate, isTrue); - expect(cField.features, contains('late')); - - expect(dField.modelType.returnType.name, equals('double')); - expect(dField.isLate, isTrue); - expect(dField.features, contains('late')); - }); - - test('Late final top level variables', () { - var initializeMe = lateFinalWithoutInitializer.publicProperties - .firstWhere((v) => v.name == 'initializeMe'); - expect(initializeMe.modelType.returnType.name, equals('String')); - expect(initializeMe.isLate, isTrue); - expect(initializeMe.features, contains('late')); - }); - - test('Opt out of Null safety', () { - var notOptedIn = optOutOfNullSafety.publicProperties - .firstWhere((v) => v.name == 'notOptedIn'); - expect(notOptedIn.isNullSafety, isFalse); - expect(notOptedIn.modelType.nullabilitySuffix, isEmpty); - }); - - test('complex nullable elements are detected and rendered correctly', () { - var complexNullableMembers = nullableElements.allClasses - .firstWhere((c) => c.name == 'ComplexNullableMembers'); - var aComplexType = complexNullableMembers.allFields - .firstWhere((f) => f.name == 'aComplexType'); - var aComplexSetterOnlyType = complexNullableMembers.allFields - .firstWhere((f) => f.name == 'aComplexSetterOnlyType'); - expect(complexNullableMembers.isNullSafety, isTrue); - expect( - complexNullableMembers.nameWithGenerics, - equals( - 'ComplexNullableMembers<T extends String?>')); - expect( - aComplexType.linkedReturnType, - equals( - 'Map<T?, String?>')); - expect(aComplexSetterOnlyType.linkedReturnType, equals( - // TODO(jcollins-g): fix wrong span class for setter-only return type (#2226) - 'List<Map<T?, String?>?>')); - }); - - test('simple nullable elements are detected and rendered correctly', () { - var nullableMembers = nullableElements.allClasses - .firstWhere((c) => c.name == 'NullableMembers'); - var initialized = nullableMembers.allFields - .firstWhere((f) => f.name == 'initialized'); - var nullableField = nullableMembers.allFields - .firstWhere((f) => f.name == 'nullableField'); - var methodWithNullables = nullableMembers.publicInstanceMethods - .firstWhere((f) => f.name == 'methodWithNullables'); - var operatorStar = nullableMembers.publicInstanceOperators - .firstWhere((f) => f.name == 'operator *'); - expect(nullableMembers.isNullSafety, isTrue); - expect( - nullableField.linkedReturnType, - equals( - 'Iterable<BigInt>?')); - expect( - methodWithNullables.linkedParams, - equals( - 'String? foo')); - expect(methodWithNullables.linkedReturnType, equals('int?')); - expect( - initialized.linkedReturnType, - equals( - 'Map<String, Map>?')); - expect( - operatorStar.linkedParams, - equals( - 'NullableMembers? nullableOther')); - }); - }, - skip: (!_nullSafetyExperimentAllowed.allows(_platformVersion) && - !_platformVersionString.contains('edge'))); }); group('HTML Injection when allowed', () { From c4a569bbdebc5ecca1680a414a7df4c39ca6f68d Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Thu, 4 Mar 2021 14:57:21 -0800 Subject: [PATCH 7/8] add markdown and more test cases --- lib/src/generator/templates.dart | 4 +++ lib/templates/md/_type.md | 5 ++++ lib/templates/md/_type_multiline.md | 7 +++++ lib/templates/md/_typedef.md | 6 ++++ lib/templates/md/_typedef_multiline.md | 6 ++++ lib/templates/md/category.md | 2 +- lib/templates/md/library.md | 2 +- lib/templates/md/typedef.md | 2 +- pubspec.yaml | 17 +---------- test/end2end/model_special_cases_test.dart | 20 ++++++------- .../lib/generalized_typedefs.dart | 28 ++++++++++++++++--- tool/grind.dart | 27 +++++++++--------- 12 files changed, 80 insertions(+), 46 deletions(-) create mode 100644 lib/templates/md/_type.md create mode 100644 lib/templates/md/_type_multiline.md create mode 100644 lib/templates/md/_typedef.md create mode 100644 lib/templates/md/_typedef_multiline.md diff --git a/lib/src/generator/templates.dart b/lib/src/generator/templates.dart index 96141e5ea3..9fd4964b75 100644 --- a/lib/src/generator/templates.dart +++ b/lib/src/generator/templates.dart @@ -70,6 +70,10 @@ const _partials_md = [ 'property', 'source_code', 'source_link', + 'type', + 'type_multiline', + 'typedef', + 'typedef_multiline', ]; abstract class _TemplatesLoader { diff --git a/lib/templates/md/_type.md b/lib/templates/md/_type.md new file mode 100644 index 0000000000..12560c75fd --- /dev/null +++ b/lib/templates/md/_type.md @@ -0,0 +1,5 @@ +##### {{{linkedName}}}{{{linkedGenericParameters}}}({{{ linkedParamsNoMetadata }}}) {{{ linkedReturnType }}} +{{>categorization}} + +{{{ oneLineDoc }}} {{{ extendedDocLink }}} {{!two spaces intentional}} +{{>features}} diff --git a/lib/templates/md/_type_multiline.md b/lib/templates/md/_type_multiline.md new file mode 100644 index 0000000000..adfbd36058 --- /dev/null +++ b/lib/templates/md/_type_multiline.md @@ -0,0 +1,7 @@ +{{#hasAnnotations}} +{{#annotations}} +- {{{.}}} +{{/annotations}} +{{/hasAnnotations}} + +{{>name_summary}}{{{genericParameters}}} = {{{linkedReturnType}}} diff --git a/lib/templates/md/_typedef.md b/lib/templates/md/_typedef.md new file mode 100644 index 0000000000..7d2453299f --- /dev/null +++ b/lib/templates/md/_typedef.md @@ -0,0 +1,6 @@ +{{#isCallable}} + {{>callable}} +{{/isCallable}} +{{^isCallable}} + {{>type}} +{{/isCallable}} diff --git a/lib/templates/md/_typedef_multiline.md b/lib/templates/md/_typedef_multiline.md new file mode 100644 index 0000000000..c1139581c3 --- /dev/null +++ b/lib/templates/md/_typedef_multiline.md @@ -0,0 +1,6 @@ +{{#isCallable}} + {{>callable_multiline}} +{{/isCallable}} +{{^isCallable}} + {{>type_multiline}} +{{/isCallable}} diff --git a/lib/templates/md/category.md b/lib/templates/md/category.md index a625d030a2..aadf6c677a 100644 --- a/lib/templates/md/category.md +++ b/lib/templates/md/category.md @@ -72,7 +72,7 @@ ## Typedefs {{#publicTypedefsSorted}} -{{>callable}} +{{>typedef}} {{/publicTypedefsSorted}} {{/hasPublicTypedefs}} diff --git a/lib/templates/md/library.md b/lib/templates/md/library.md index b4fa38d91d..eb0fe60236 100644 --- a/lib/templates/md/library.md +++ b/lib/templates/md/library.md @@ -79,7 +79,7 @@ ## Typedefs {{#library.publicTypedefsSorted}} -{{>callable}} +{{>typedef}} {{/library.publicTypedefsSorted}} {{/library.hasPublicTypedefs}} diff --git a/lib/templates/md/typedef.md b/lib/templates/md/typedef.md index bed210a4a3..8e8271dcf6 100644 --- a/lib/templates/md/typedef.md +++ b/lib/templates/md/typedef.md @@ -9,7 +9,7 @@ {{/self}} {{#typeDef}} -{{>callable_multiline}} +{{>typedef_multiline}} {{>documentation}} diff --git a/pubspec.yaml b/pubspec.yaml index 3a930ca580..3f1a58110b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ environment: sdk: '>=2.11.99 <3.0.0' dependencies: - analyzer: ^1.0.0 + analyzer: ^1.1.0 args: ^2.0.0 charcode: ^1.2.0 collection: ^1.2.0 @@ -40,18 +40,3 @@ dev_dependencies: executables: dartdoc: null - -dependency_overrides: - args: ^2.0.0-nullsafety.0 - cli_util: ^0.3.0-nullsafety.0 - crypto: ^3.0.0-nullsafety.0 - glob: ^2.0.0-nullsafety.0 - package_config: ^2.0.0-nullsafety.0 - pub_semver: ^2.0.0-nullsafety.0 - yaml: ^3.0.0-nullsafety.0 - analyzer: - path: '/Users/jcollins/dart/sdk/sdk/pkg/analyzer' - _fe_analyzer_shared: - path: '/Users/jcollins/dart/sdk/sdk/pkg/_fe_analyzer_shared' - #meta: - # path: '/Users/jcollins/dart/sdk/sdk/pkg/meta' diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index a44acb287d..c6448d8a76 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -97,20 +97,20 @@ void main() { T7 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T7'); }); - void expectTypedefs(Typedef t, String modelTypeToString, String genericParameters) { + void expectTypedefs(Typedef t, String modelTypeToString, Iterable genericParameters) { expect(t.modelType.toString(), equals(modelTypeToString)); - expect(t.genericParameters, equals(genericParameters)); + expect(t.genericTypeParameters.map((p) => p.toString()), orderedEquals(genericParameters)); } test('basic non-function typedefs work', () { - expectTypedefs(T0, 'void', ''); - expectTypedefs(T1, 'Function', ''); - expectTypedefs(T2, 'List', ''); - expectTypedefs(T3, '', ''); - expectTypedefs(T4, '', ''); - expectTypedefs(T5, '', ''); - expectTypedefs(T6, '', ''); - expectTypedefs(T7, '', ''); + expectTypedefs(T0, 'void', []); + expectTypedefs(T1, 'Function', []); + expectTypedefs(T2, 'List', ['out X']); + expectTypedefs(T3, 'Map', ['out X', 'out Y']); + expectTypedefs(T4, 'void Function()', []); + expectTypedefs(T5, 'X Function(X, {X name})', ['inout X']); + expectTypedefs(T6, 'X Function(Y, [Map])', ['out X', 'in Y']); + expectTypedefs(T7, 'X Function(Y, [Map])', ['out X extends String', 'in Y extends List']); }); }, skip: (!_generalizedTypedefsAllowed.allows(_platformVersion))); }); diff --git a/testing/test_package_experiments/lib/generalized_typedefs.dart b/testing/test_package_experiments/lib/generalized_typedefs.dart index c8a10ea5ec..658c8cd22a 100644 --- a/testing/test_package_experiments/lib/generalized_typedefs.dart +++ b/testing/test_package_experiments/lib/generalized_typedefs.dart @@ -6,6 +6,8 @@ /// typedef syntax, and produce correct results. library generalized_typedefs; +// from basic_syntax_test (Dart SDK) + typedef T0 = void; typedef T1 = Function; typedef T2 = List; @@ -15,8 +17,26 @@ typedef T5 = X Function(X, {X name}); typedef T6 = X Function(Y, [Map]); typedef T7> = X Function(Y, [Map]); -void main() { - // ignore:unused_local_variable - var ensure_usage = [T0, T1, T2, T3, T4, T5, T6, T7]; - print('hi'); +class C1 {} + +typedef T8 = C1; + +abstract class C extends T8 { + T0 f; + T1 g(T2 a, T3 b); + + T2 operator +(T2 other) => other; + + static final T4 h = (){}; + static T5? i; + + T7> get j; + + set k(T6 value); } + +extension E on T6 { + static T4 f = () {}; + + T2 myMethod() => [5]; +} \ No newline at end of file diff --git a/tool/grind.dart b/tool/grind.dart index 5526c0f182..9565788ad0 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -226,10 +226,7 @@ void analyze() async { '--fatal-infos', '--options', 'analysis_options_presubmit.yaml', - 'bin', - 'lib', - 'test', - 'tool', + '.' ], ); } @@ -241,22 +238,26 @@ void dartfmt() async { // Filter out test packages as they always have strange formatting. // Passing parameters to dartfmt for directories to search results in // filenames being stripped of the dirname so we have to filter here. - void addFileToFix(String fileName) { + void addFileToFix(String base, String fileName) { var pathComponents = path.split(fileName); if (pathComponents.isNotEmpty && pathComponents.first == 'testing') { return; } - filesToFix.add(fileName); + filesToFix.add(path.join(base, fileName)); } log('Validating dartfmt with version ${Platform.version}'); - await SubprocessLauncher('dartfmt').runStreamed( - sdkBin('dartfmt'), - [ - '-n', - '.', - ], - perLine: addFileToFix); + // TODO(jcollins-g): return to global once dartfmt can handle generic + // type aliases + for (var subDirectory in ['bin', 'lib', 'test', 'tool', path.join('testing/test_package')]) { + await SubprocessLauncher('dartfmt').runStreamed( + sdkBin('dartfmt'), + [ + '-n', + subDirectory, + ], + perLine: (n) => addFileToFix(subDirectory, n)); + } if (filesToFix.isNotEmpty) { fail( 'dartfmt found files needing reformatting. Use this command to reformat:\n' From 1097818763ffbd1b49a77abe4dbeab9fb07d317e Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Thu, 4 Mar 2021 14:58:47 -0800 Subject: [PATCH 8/8] dartfmt --- lib/src/model/model_element.dart | 3 +-- lib/src/model/typedef.dart | 12 ++++++------ test/end2end/model_special_cases_test.dart | 15 +++++++++------ test/end2end/model_test.dart | 2 +- .../test_package/lib/completely_empty_lib.dart | 2 +- testing/test_package/lib/example.dart | 3 ++- testing/test_package/lib/fake.dart | 5 ++--- .../features/late_final_without_initializer.dart | 1 - .../features/nnbd_class_member_declarations.dart | 13 ++++++++----- .../lib/features/nullable_elements.dart | 2 +- testing/test_package/lib/implementors.dart | 3 ++- testing/test_package/lib/src/gadget.dart | 3 +-- .../lib/src/intermediate_implements.dart | 2 +- testing/test_package/lib/src/nodocme.dart | 1 - testing/test_package/lib/src/reexport_this.dart | 4 +--- testing/test_package/lib/src/shadowing_lib.dart | 2 +- testing/test_package/lib/src/somelib.dart | 7 +++---- testing/test_package/lib/unrelated_factories.dart | 2 +- tool/grind.dart | 15 ++++++++------- 19 files changed, 49 insertions(+), 48 deletions(-) diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index a40d90a680..809b8df559 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -548,8 +548,7 @@ abstract class ModelElement extends Canonicalization } bool get isCallable => - element is FunctionTypedElement || - element is FunctionTypeAliasElement; + element is FunctionTypedElement || element is FunctionTypeAliasElement; ModelElement buildCanonicalModelElement() { Container preferredClass; diff --git a/lib/src/model/typedef.dart b/lib/src/model/typedef.dart index 817ffaaec9..d49bfca6b8 100644 --- a/lib/src/model/typedef.dart +++ b/lib/src/model/typedef.dart @@ -10,8 +10,7 @@ import 'package:dartdoc/src/render/typedef_renderer.dart'; class Typedef extends ModelElement with TypeParameters, Categorization implements EnclosedElement { - Typedef(TypeAliasElement element, Library library, - PackageGraph packageGraph) + Typedef(TypeAliasElement element, Library library, PackageGraph packageGraph) : super(element, library, packageGraph); DartType get aliasedType => element.aliasedType; @@ -28,7 +27,8 @@ class Typedef extends ModelElement @override String get genericParameters => _renderer.renderGenericParameters(this); - List get genericTypeParameters => element.typeParameters; + List get genericTypeParameters => + element.typeParameters; @override String get filePath => '${library.dirName}/$fileName'; @@ -61,8 +61,8 @@ class Typedef extends ModelElement /// A typedef referring to a function type. class FunctionTypedef extends Typedef { - FunctionTypedef(TypeAliasElement element, Library library, - PackageGraph packageGraph) + FunctionTypedef( + TypeAliasElement element, Library library, PackageGraph packageGraph) : super(element, library, packageGraph); @override @@ -79,4 +79,4 @@ class FunctionTypedef extends Typedef { } return super.genericTypeParameters; } -} \ No newline at end of file +} diff --git a/test/end2end/model_special_cases_test.dart b/test/end2end/model_special_cases_test.dart index c6448d8a76..9d8ea3ab16 100644 --- a/test/end2end/model_special_cases_test.dart +++ b/test/end2end/model_special_cases_test.dart @@ -75,7 +75,7 @@ void main() { } final _generalizedTypedefsAllowed = - VersionRange(min: Version.parse('2.13.0-0'), includeMin: true); + VersionRange(min: Version.parse('2.13.0-0'), includeMin: true); // Experimental features not yet enabled by default. Move tests out of this // block when the feature is enabled by default. group('Experiments', () { @@ -85,8 +85,8 @@ void main() { setUpAll(() async { generalizedTypedefs = (await _testPackageGraphExperiments) - .libraries - .firstWhere((l) => l.name == 'generalized_typedefs'); + .libraries + .firstWhere((l) => l.name == 'generalized_typedefs'); T0 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T0'); T1 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T1'); T2 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T2'); @@ -97,9 +97,11 @@ void main() { T7 = generalizedTypedefs.typedefs.firstWhere((a) => a.name == 'T7'); }); - void expectTypedefs(Typedef t, String modelTypeToString, Iterable genericParameters) { + void expectTypedefs(Typedef t, String modelTypeToString, + Iterable genericParameters) { expect(t.modelType.toString(), equals(modelTypeToString)); - expect(t.genericTypeParameters.map((p) => p.toString()), orderedEquals(genericParameters)); + expect(t.genericTypeParameters.map((p) => p.toString()), + orderedEquals(genericParameters)); } test('basic non-function typedefs work', () { @@ -110,7 +112,8 @@ void main() { expectTypedefs(T4, 'void Function()', []); expectTypedefs(T5, 'X Function(X, {X name})', ['inout X']); expectTypedefs(T6, 'X Function(Y, [Map])', ['out X', 'in Y']); - expectTypedefs(T7, 'X Function(Y, [Map])', ['out X extends String', 'in Y extends List']); + expectTypedefs(T7, 'X Function(Y, [Map])', + ['out X extends String', 'in Y extends List']); }); }, skip: (!_generalizedTypedefsAllowed.allows(_platformVersion))); }); diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index 64933b99a2..6a4659ace3 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -4139,4 +4139,4 @@ class StringName extends Nameable { @override String toString() => name; -} \ No newline at end of file +} diff --git a/testing/test_package/lib/completely_empty_lib.dart b/testing/test_package/lib/completely_empty_lib.dart index 93ce5d2949..fdc4933219 100644 --- a/testing/test_package/lib/completely_empty_lib.dart +++ b/testing/test_package/lib/completely_empty_lib.dart @@ -1 +1 @@ -// @dart=2.9 \ No newline at end of file +// @dart=2.9 diff --git a/testing/test_package/lib/example.dart b/testing/test_package/lib/example.dart index de03905b49..275eb5e15c 100644 --- a/testing/test_package/lib/example.dart +++ b/testing/test_package/lib/example.dart @@ -201,7 +201,8 @@ class Apple { /** * fieldWithTypedef docs here */ - final ParameterizedTypedef fieldWithTypedef = (bool a, int b) => 'hello, ${a} ${b}'; + final ParameterizedTypedef fieldWithTypedef = + (bool a, int b) => 'hello, ${a} ${b}'; } /// Extension on Apple diff --git a/testing/test_package/lib/fake.dart b/testing/test_package/lib/fake.dart index 520c4a48eb..74734caaac 100644 --- a/testing/test_package/lib/fake.dart +++ b/testing/test_package/lib/fake.dart @@ -1229,12 +1229,11 @@ class _Super5 implements _Super2 {} class Super6 implements _Super5 {} - abstract class IntermediateAbstract extends Object { /// This is an override. @override - bool operator==(Object other) {} + bool operator ==(Object other) {} } /// This should inherit [==] from [IntermediateAbstract]. -class IntermediateAbstractSubclass extends IntermediateAbstract {} \ No newline at end of file +class IntermediateAbstractSubclass extends IntermediateAbstract {} diff --git a/testing/test_package/lib/features/late_final_without_initializer.dart b/testing/test_package/lib/features/late_final_without_initializer.dart index 27765b26a2..8585247837 100644 --- a/testing/test_package/lib/features/late_final_without_initializer.dart +++ b/testing/test_package/lib/features/late_final_without_initializer.dart @@ -17,4 +17,3 @@ class C { dField = param * 8.854 * pow(10, -12); } } - diff --git a/testing/test_package/lib/features/nnbd_class_member_declarations.dart b/testing/test_package/lib/features/nnbd_class_member_declarations.dart index 7d13186a1d..16014edf34 100644 --- a/testing/test_package/lib/features/nnbd_class_member_declarations.dart +++ b/testing/test_package/lib/features/nnbd_class_member_declarations.dart @@ -6,11 +6,14 @@ library nnbd_class_member_declarations; /// Test required and covariant parameters abstract class B { - m1(int some, regular, covariant parameters, { - required p1, - int p2 = 3, - required covariant p3, - required covariant int p4, + m1( + int some, + regular, + covariant parameters, { + required p1, + int p2 = 3, + required covariant p3, + required covariant int p4, }); m2(int sometimes, we, [String have, double optionals]); } diff --git a/testing/test_package/lib/features/nullable_elements.dart b/testing/test_package/lib/features/nullable_elements.dart index 94ee591a3a..9607b2694c 100644 --- a/testing/test_package/lib/features/nullable_elements.dart +++ b/testing/test_package/lib/features/nullable_elements.dart @@ -35,4 +35,4 @@ class ComplexNullableMembers { void set aComplexSetterOnlyType(List?> value) => null; X? aMethod(X? f) => null; -} \ No newline at end of file +} diff --git a/testing/test_package/lib/implementors.dart b/testing/test_package/lib/implementors.dart index 050d1e120b..33d041cbde 100644 --- a/testing/test_package/lib/implementors.dart +++ b/testing/test_package/lib/implementors.dart @@ -15,4 +15,5 @@ abstract class _APrivateThingToImplement implements ImplementBase {} abstract class ImplementerOfThings implements IntermediateImplementer {} -abstract class ImplementerOfDeclaredPrivateClasses implements _APrivateThingToImplement {} \ No newline at end of file +abstract class ImplementerOfDeclaredPrivateClasses + implements _APrivateThingToImplement {} diff --git a/testing/test_package/lib/src/gadget.dart b/testing/test_package/lib/src/gadget.dart index 2044fa0c81..ceb7c784eb 100644 --- a/testing/test_package/lib/src/gadget.dart +++ b/testing/test_package/lib/src/gadget.dart @@ -8,5 +8,4 @@ class _GadgetBase { int get gadgetGetter => 5; } - -class Gadget extends _GadgetBase {} \ No newline at end of file +class Gadget extends _GadgetBase {} diff --git a/testing/test_package/lib/src/intermediate_implements.dart b/testing/test_package/lib/src/intermediate_implements.dart index 8b194e03df..e9d85c1453 100644 --- a/testing/test_package/lib/src/intermediate_implements.dart +++ b/testing/test_package/lib/src/intermediate_implements.dart @@ -9,4 +9,4 @@ library intermediate_implements; import 'package:test_package/implementors.dart'; -abstract class IntermediateImplementer implements ImplementBase {} \ No newline at end of file +abstract class IntermediateImplementer implements ImplementBase {} diff --git a/testing/test_package/lib/src/nodocme.dart b/testing/test_package/lib/src/nodocme.dart index 94049dd895..36d9b3f4c2 100644 --- a/testing/test_package/lib/src/nodocme.dart +++ b/testing/test_package/lib/src/nodocme.dart @@ -11,4 +11,3 @@ library nodocme; class NodocMeImplementation {} class MeNeitherEvenWithoutADocComment {} - diff --git a/testing/test_package/lib/src/reexport_this.dart b/testing/test_package/lib/src/reexport_this.dart index 6b33557d79..77255cf53c 100644 --- a/testing/test_package/lib/src/reexport_this.dart +++ b/testing/test_package/lib/src/reexport_this.dart @@ -1,6 +1,5 @@ // @dart=2.9 - library reexport_this; /// {@template example:templateMemberTest} @@ -10,5 +9,4 @@ library reexport_this; /// /// And if I do, a test should fail. /// {@endtemplate} -class ClassTemplateOneLiner { -} \ No newline at end of file +class ClassTemplateOneLiner {} diff --git a/testing/test_package/lib/src/shadowing_lib.dart b/testing/test_package/lib/src/shadowing_lib.dart index 9491e37b20..72ea97805c 100644 --- a/testing/test_package/lib/src/shadowing_lib.dart +++ b/testing/test_package/lib/src/shadowing_lib.dart @@ -6,4 +6,4 @@ class ADuplicateClass { bool get aGetter => true; } -class SomeMoreClassDeclaration {} \ No newline at end of file +class SomeMoreClassDeclaration {} diff --git a/testing/test_package/lib/src/somelib.dart b/testing/test_package/lib/src/somelib.dart index ad3da7a8e9..b8ab5cea58 100644 --- a/testing/test_package/lib/src/somelib.dart +++ b/testing/test_package/lib/src/somelib.dart @@ -14,17 +14,16 @@ class BaseReexported { String action; } -class ExtendedBaseReexported extends BaseReexported { -} +class ExtendedBaseReexported extends BaseReexported {} /// A private extension. extension _Unseen on Object { - void doYouSeeMe() { } + void doYouSeeMe() {} } /// An extension without a name extension on List { - void somethingNew() { } + void somethingNew() {} } /// [_Unseen] is not seen, but [DocumentMe] is. diff --git a/testing/test_package/lib/unrelated_factories.dart b/testing/test_package/lib/unrelated_factories.dart index 9699fc9932..ad11cbe132 100644 --- a/testing/test_package/lib/unrelated_factories.dart +++ b/testing/test_package/lib/unrelated_factories.dart @@ -11,4 +11,4 @@ class AB { factory AB.fromMap(Map map) => AB._AB(); AB._AB(); -} \ No newline at end of file +} diff --git a/tool/grind.dart b/tool/grind.dart index 9565788ad0..93d561ea6e 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -222,12 +222,7 @@ void updateThirdParty() async { void analyze() async { await SubprocessLauncher('analyze').runStreamed( sdkBin('dartanalyzer'), - [ - '--fatal-infos', - '--options', - 'analysis_options_presubmit.yaml', - '.' - ], + ['--fatal-infos', '--options', 'analysis_options_presubmit.yaml', '.'], ); } @@ -249,7 +244,13 @@ void dartfmt() async { log('Validating dartfmt with version ${Platform.version}'); // TODO(jcollins-g): return to global once dartfmt can handle generic // type aliases - for (var subDirectory in ['bin', 'lib', 'test', 'tool', path.join('testing/test_package')]) { + for (var subDirectory in [ + 'bin', + 'lib', + 'test', + 'tool', + path.join('testing/test_package') + ]) { await SubprocessLauncher('dartfmt').runStreamed( sdkBin('dartfmt'), [