From bd1f467f67cce25d3be7e7dc5c7ce97946f59c74 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Wed, 21 Feb 2024 16:34:15 -0800 Subject: [PATCH 1/2] Bump all enum tests to use enhanced enums --- lib/src/model/getter_setter_combo.dart | 47 +++++++++++++++++++++----- test/enum_test.dart | 42 +++++++++++++++++------ test/templates/enum_test.dart | 9 ++--- 3 files changed, 72 insertions(+), 26 deletions(-) diff --git a/lib/src/model/getter_setter_combo.dart b/lib/src/model/getter_setter_combo.dart index 7cb342aec3..9ac9990d22 100644 --- a/lib/src/model/getter_setter_combo.dart +++ b/lib/src/model/getter_setter_combo.dart @@ -73,15 +73,15 @@ mixin GetterSetterCombo on ModelElement { return original; } var target = modelBuilder.fromElement(staticElement) as Constructor; - if (target.enclosingElement is! Class) return original; - var targetClass = target.enclosingElement as Class; - // TODO(jcollins-g): this logic really should be integrated into Constructor, - // but that's not trivial because of linkedName's usage. - if (targetClass.name == target.name) { + var enclosingElement = target.enclosingElement; + if (enclosingElement is! Class) return original; + // TODO(jcollins-g): this logic really should be integrated into + // `Constructor`, but that's not trivial because of `linkedName`'s usage. + if (enclosingElement.name == target.name) { return original.replaceAll(constructorName, target.linkedName); } - return original.replaceAll('${targetClass.name}.${target.name}', - '${targetClass.linkedName}.${target.linkedName}'); + return original.replaceAll('${enclosingElement.name}.${target.name}', + '${enclosingElement.linkedName}.${target.linkedName}'); } @override @@ -110,8 +110,37 @@ mixin GetterSetterCombo on ModelElement { String get constantValueTruncated => linkifyConstantValue(truncateString(constantValueBase, 200)); - late final String constantValueBase = const HtmlEscape(HtmlEscapeMode.unknown) - .convert(constantInitializer?.toString() ?? ''); + late final String constantValueBase = () { + final constantInitializer = this.constantInitializer; + if (constantInitializer == null) { + return ''; + } + + var initializerString = constantInitializer.toString(); + + final self = this; + if (self is! EnumField || + constantInitializer is! InstanceCreationExpression) { + return _htmlEscape.convert(initializerString); + } + + initializerString = 'const $initializerString'; + + var isImplicitConstructorCall = constantInitializer + .constructorName.staticElement?.isDefaultConstructor ?? + false; + if (isImplicitConstructorCall) { + // For an enum value with an implicit constructor call (like + // `enum E { one, two; }`), `constantInitializer.toString()` does not + // include the implicit enum index argument (it is something like + // `const E()`). We must manually include it. + initializerString = + initializerString.replaceFirst('()', '(${self.index})'); + } + return _htmlEscape.convert(initializerString); + }(); + + static const _htmlEscape = HtmlEscape(HtmlEscapeMode.unknown); late final bool hasPublicGetter = hasGetter && getter!.isPublic; diff --git a/test/enum_test.dart b/test/enum_test.dart index f3621bfbfa..917baac2e5 100644 --- a/test/enum_test.dart +++ b/test/enum_test.dart @@ -394,7 +394,19 @@ class C {} ); } - void test_valuesHaveAConstantValueImplementation() async { + void test_constantValue_implicitConstructorCall() async { + var library = await bootPackageWithLibrary(''' +enum E { one, two } +'''); + + var oneValue = library.enums.named('E').publicEnumValues.named('one'); + expect(oneValue.constantValueTruncated, 'const E(0)'); + + var twoValue = library.enums.named('E').publicEnumValues.named('two'); + expect(twoValue.constantValueTruncated, 'const E(1)'); + } + + void test_constantValue_explicitConstructorCall() async { var library = await bootPackageWithLibrary(''' enum E { one.named(1), @@ -402,23 +414,33 @@ enum E { final int x; - /// A named constructor. const E.named(this.x); } - -enum F { one, two } '''); var eOneValue = library.enums.named('E').publicEnumValues.named('one'); - expect(eOneValue.constantValueTruncated, 'E.named(1)'); + expect(eOneValue.constantValueTruncated, 'const E.named(1)'); var eTwoValue = library.enums.named('E').publicEnumValues.named('two'); - expect(eTwoValue.constantValueTruncated, 'E.named(2)'); + expect(eTwoValue.constantValueTruncated, 'const E.named(2)'); + } - var fOneValue = library.enums.named('F').publicEnumValues.named('one'); - expect(fOneValue.constantValueTruncated, 'F()'); + void test_constantValue_explicitConstructorCall_zeroConstructorArgs() async { + var library = await bootPackageWithLibrary(''' +enum E { + one.named1(), + two.named2(); - var fTwoValue = library.enums.named('F').publicEnumValues.named('two'); - expect(fTwoValue.constantValueTruncated, 'F()'); + final int x; + + const E.named1() : x = 1; + const E.named2() : x = 2; +} +'''); + var eOneValue = library.enums.named('E').publicEnumValues.named('one'); + expect(eOneValue.constantValueTruncated, 'const E.named1()'); + + var eTwoValue = library.enums.named('E').publicEnumValues.named('two'); + expect(eTwoValue.constantValueTruncated, 'const E.named2()'); } } diff --git a/test/templates/enum_test.dart b/test/templates/enum_test.dart index 612001f2fa..8c36a3303f 100644 --- a/test/templates/enum_test.dart +++ b/test/templates/enum_test.dart @@ -19,7 +19,7 @@ void main() async { late List enumWithDefaultConstructorLines; late List enumWithDefaultConstructorRightSidebarLines; - group('enhanced enums', skip: !enhancedEnumsAllowed, () { + group('enums', () { setUpAll(() async { final packageMetaProvider = testPackageMetaProvider; final resourceProvider = @@ -31,11 +31,6 @@ name: enums version: 0.0.1 environment: sdk: '>=2.17.0-0 <3.0.0' -''', - analysisOptions: ''' -analyzer: - enable-experiment: - - enhanced-enums ''', libFiles: [ d.file('lib.dart', ''' @@ -194,7 +189,7 @@ enum EnumWithDefaultConstructor { matches('one'), matches('

Doc comment for one.

'), matches( - r'E<int>.named\(1\)'), + r'const E<int>.named\(1\)'), ]), ); }); From 7ccf266f71ad7a3090b1393bce70db9c34f3f2a2 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Thu, 22 Feb 2024 10:46:08 -0800 Subject: [PATCH 2/2] feedback --- lib/src/model/getter_setter_combo.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/model/getter_setter_combo.dart b/lib/src/model/getter_setter_combo.dart index 9ac9990d22..630117c57a 100644 --- a/lib/src/model/getter_setter_combo.dart +++ b/lib/src/model/getter_setter_combo.dart @@ -133,7 +133,8 @@ mixin GetterSetterCombo on ModelElement { // For an enum value with an implicit constructor call (like // `enum E { one, two; }`), `constantInitializer.toString()` does not // include the implicit enum index argument (it is something like - // `const E()`). We must manually include it. + // `const E()`). We must manually include it. See + // https://github.com/dart-lang/sdk/issues/54988. initializerString = initializerString.replaceFirst('()', '(${self.index})'); }