From df0f4761773fba9b21ff47ad3863145f73fa366e Mon Sep 17 00:00:00 2001 From: Chloe Stefantsova Date: Tue, 18 Jan 2022 13:52:34 +0000 Subject: [PATCH] [cfe] Allow abstract classes to implement and extend Enum Part of https://github.com/dart-lang/sdk/issues/47453 Change-Id: I6782b4a9f13f95f626f41c311c05ce949649c828 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/228562 Reviewed-by: Johnni Winther Commit-Queue: Chloe Stefantsova --- .../lib/src/messages/codes_generated.dart | 24 ++++ .../lib/src/fasta/denylisted_classes.dart | 1 - .../lib/src/fasta/source/source_loader.dart | 32 ++++- pkg/front_end/messages.status | 2 + pkg/front_end/messages.yaml | 3 + .../test/spell_checking_list_messages.txt | 1 + .../test/spell_checking_list_tests.txt | 2 + .../enhanced_enums/enum_as_supertype.dart | 40 ++++++ .../enum_as_supertype.dart.strong.expect | 128 ++++++++++++++++++ ...s_supertype.dart.strong.transformed.expect | 128 ++++++++++++++++++ ...m_as_supertype.dart.textual_outline.expect | 18 +++ .../enum_as_supertype.dart.weak.expect | 128 ++++++++++++++++++ ...enum_as_supertype.dart.weak.modular.expect | 128 ++++++++++++++++++ ...enum_as_supertype.dart.weak.outline.expect | 100 ++++++++++++++ ..._as_supertype.dart.weak.transformed.expect | 128 ++++++++++++++++++ .../enum_as_supertype_error.dart | 13 ++ ...enum_as_supertype_error.dart.strong.expect | 69 ++++++++++ ...rtype_error.dart.strong.transformed.expect | 69 ++++++++++ ...upertype_error.dart.textual_outline.expect | 9 ++ ...error.dart.textual_outline_modelled.expect | 9 ++ .../enum_as_supertype_error.dart.weak.expect | 69 ++++++++++ ...s_supertype_error.dart.weak.modular.expect | 69 ++++++++++ ...s_supertype_error.dart.weak.outline.expect | 73 ++++++++++ ...pertype_error.dart.weak.transformed.expect | 69 ++++++++++ pkg/front_end/testcases/strong.status | 1 + .../testcases/text_serialization.status | 1 + .../testcases/textual_outline.status | 1 + pkg/front_end/testcases/weak.status | 1 + 28 files changed, 1311 insertions(+), 5 deletions(-) create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index 754214a490e..7f4e3213f40 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -2806,6 +2806,30 @@ const MessageCode messageEnumInstantiation = const MessageCode( analyzerCodes: ["INSTANTIATE_ENUM"], problemMessage: r"""Enums can't be instantiated."""); +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template + templateEnumSupertypeOfNonAbstractClass = + const Template( + problemMessageTemplate: + r"""Non-abstract class '#name' has 'Enum' as a superinterface.""", + withArguments: _withArgumentsEnumSupertypeOfNonAbstractClass); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeEnumSupertypeOfNonAbstractClass = + const Code( + "EnumSupertypeOfNonAbstractClass", +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsEnumSupertypeOfNonAbstractClass(String name) { + if (name.isEmpty) throw 'No name provided'; + name = demangleMixinApplicationName(name); + return new Message(codeEnumSupertypeOfNonAbstractClass, + problemMessage: + """Non-abstract class '${name}' has 'Enum' as a superinterface.""", + arguments: {'name': name}); +} + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Code codeEqualityCannotBeEqualityOperand = messageEqualityCannotBeEqualityOperand; diff --git a/pkg/front_end/lib/src/fasta/denylisted_classes.dart b/pkg/front_end/lib/src/fasta/denylisted_classes.dart index 5df37075487..345ec129e9d 100644 --- a/pkg/front_end/lib/src/fasta/denylisted_classes.dart +++ b/pkg/front_end/lib/src/fasta/denylisted_classes.dart @@ -8,7 +8,6 @@ const List denylistedCoreClasses = [ "int", "num", "double", - "Enum", "String", "Null" ]; diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart index d764604567c..9795167bc66 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart @@ -1648,6 +1648,8 @@ severity: $severity denylistedCoreClasses[i], required: true) as ClassBuilder); } + ClassBuilder enumClass = + coreLibrary.lookupLocalMember("Enum", required: true) as ClassBuilder; if (typedDataLibrary != null) { for (int i = 0; i < denylistedTypedDataClasses.length; i++) { // Allow the member to not exist. If it doesn't, nobody can extend it. @@ -1664,8 +1666,8 @@ severity: $severity topologicalSort(classGraph); List classes = result.sortedVertices; for (SourceClassBuilder cls in classes) { - checkClassSupertypes( - cls, classGraph.directSupertypeMap[cls]!, denyListedClasses); + checkClassSupertypes(cls, classGraph.directSupertypeMap[cls]!, + denyListedClasses, enumClass); } List classesWithCycles = result.cyclicVertices; @@ -1708,10 +1710,30 @@ severity: $severity } } + bool checkEnumSupertypeIsDenylisted(SourceClassBuilder cls) { + if (!cls.library.enableEnhancedEnumsInLibrary) { + cls.addProblem( + templateExperimentNotEnabled.withArguments('enhanced-enums', + cls.library.enableEnhancedEnumsVersionInLibrary.toText()), + cls.charOffset, + noLength); + return true; + } else { + if (!cls.isAbstract) { + cls.addProblem( + templateEnumSupertypeOfNonAbstractClass.withArguments(cls.name), + cls.charOffset, + noLength); + } + return false; + } + } + void checkClassSupertypes( SourceClassBuilder cls, Map directSupertypeMap, - Set denyListedClasses) { + Set denyListedClasses, + ClassBuilder enumClass) { // Check that the direct supertypes aren't deny-listed or enums. List directSupertypes = directSupertypeMap.keys.toList(); @@ -1721,7 +1743,9 @@ severity: $severity cls.addProblem(templateExtendingEnum.withArguments(supertype.name), cls.charOffset, noLength); } else if (!cls.library.mayImplementRestrictedTypes && - denyListedClasses.contains(supertype)) { + (denyListedClasses.contains(supertype) || + identical(supertype, enumClass) && + checkEnumSupertypeIsDenylisted(cls))) { TypeAliasBuilder? aliasBuilder = directSupertypeMap[supertype]; if (aliasBuilder != null) { cls.addProblem( diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 0c1fb2bd343..c7e820fb6d2 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -218,6 +218,8 @@ EnumDeclaresConstFactory/example: Fail EnumDeclaresFactory/analyzerCode: Fail EnumDeclaresFactory/example: Fail EnumInstantiation/example: Fail +EnumSupertypeOfNonAbstractClass/analyzerCode: Fail +EnumSupertypeOfNonAbstractClass/example: Fail EqualityCannotBeEqualityOperand/part_wrapped_script1: Fail EqualityCannotBeEqualityOperand/part_wrapped_script2: Fail EqualityCannotBeEqualityOperand/script1: Fail diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 8ba9698a2d2..55b8acb6e3a 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -5455,3 +5455,6 @@ PositionalSuperParametersAndArguments: SuperInitializerParameter: problemMessage: "This is the super-initializer parameter." severity: CONTEXT + +EnumSupertypeOfNonAbstractClass: + problemMessage: "Non-abstract class '#name' has 'Enum' as a superinterface." diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt index 30bf90dd2b9..f38dd3a193d 100644 --- a/pkg/front_end/test/spell_checking_list_messages.txt +++ b/pkg/front_end/test/spell_checking_list_messages.txt @@ -75,6 +75,7 @@ stringokempty struct<#name structs super.namedconstructor +superinterface supermixin team this.namedconstructor diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt index 3a7144fdb58..54f7ba15827 100644 --- a/pkg/front_end/test/spell_checking_list_tests.txt +++ b/pkg/front_end/test/spell_checking_list_tests.txt @@ -321,7 +321,9 @@ dw dyn e's e2e +ea ease +eb ec echo edits diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart new file mode 100644 index 00000000000..ddee41a2e20 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2022, 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. + +abstract class A extends Enum { // Ok. + int get foo => index; +} + +enum EA with A { element } + +abstract class B implements Enum { // Ok. + int get foo => index; +} + +enum EB with B { element } + +mixin M on Enum { // Ok. + int get foo => index; +} + +enum EM with M { element } + +mixin N implements Enum { // Ok. + int get foo => index; +} + +enum EN with N { element } + +expectEquals(x, y) { + if (x != y) { + throw "Expected '$x' to be equal to '$y'."; + } +} + +main() { + expectEquals(EA.element.foo, EA.element.index); + expectEquals(EB.element.foo, EB.element.index); + expectEquals(EM.element.foo, EM.element.index); + expectEquals(EN.element.foo, EN.element.index); +} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.expect new file mode 100644 index 00000000000..95879d2618d --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.expect @@ -0,0 +1,128 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +abstract class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EA&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EA&_Enum&A + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::A::foo}; +} +class EA extends self::_EA&_Enum&A /*isEnum*/ { + static const field core::List values = #C4; + static const field self::EA element = #C3; + const constructor •(core::int index, core::String name) → self::EA + : super self::_EA&_Enum&A::•(index, name) + ; + method toString() → core::String + ; +} +abstract class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EB&_Enum&B = core::_Enum with self::B /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EB&_Enum&B + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::B::foo}; +} +class EB extends self::_EB&_Enum&B /*isEnum*/ { + static const field core::List values = #C6; + static const field self::EB element = #C5; + const constructor •(core::int index, core::String name) → self::EB + : super self::_EB&_Enum&B::•(index, name) + ; + method toString() → core::String + ; +} +abstract class M extends core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EM&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EM&_Enum&M + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::M::foo}; +} +class EM extends self::_EM&_Enum&M /*isEnum*/ { + static const field core::List values = #C8; + static const field self::EM element = #C7; + const constructor •(core::int index, core::String name) → self::EM + : super self::_EM&_Enum&M::•(index, name) + ; + method toString() → core::String + ; +} +abstract class N extends core::Object implements core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EN&_Enum&N = core::_Enum with self::N /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EN&_Enum&N + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::N::foo}; +} +class EN extends self::_EN&_Enum&N /*isEnum*/ { + static const field core::List values = #C10; + static const field self::EN element = #C9; + const constructor •(core::int index, core::String name) → self::EN + : super self::_EN&_Enum&N::•(index, name) + ; + method toString() → core::String + ; +} +static method expectEquals(dynamic x, dynamic y) → dynamic { + if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) { + throw "Expected '${x}' to be equal to '${y}'."; + } +} +static method main() → dynamic { + self::expectEquals(#C3.{self::_EA&_Enum&A::foo}{core::int}, #C3.{core::_Enum::index}{core::int}); + self::expectEquals(#C5.{self::_EB&_Enum&B::foo}{core::int}, #C5.{core::_Enum::index}{core::int}); + self::expectEquals(#C7.{self::_EM&_Enum&M::foo}{core::int}, #C7.{core::_Enum::index}{core::int}); + self::expectEquals(#C9.{self::_EN&_Enum&N::foo}{core::int}, #C9.{core::_Enum::index}{core::int}); +} + +constants { + #C1 = 0 + #C2 = "element" + #C3 = self::EA {index:#C1, _name:#C2} + #C4 = [#C3] + #C5 = self::EB {index:#C1, _name:#C2} + #C6 = [#C5] + #C7 = self::EM {index:#C1, _name:#C2} + #C8 = [#C7] + #C9 = self::EN {index:#C1, _name:#C2} + #C10 = [#C9] +} + + +Constructor coverage from constants: +org-dartlang-testcase:///enum_as_supertype.dart: +- EA. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _EA&_Enum&A. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9) +- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9) +- EB. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- _EB&_Enum&B. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- EM. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- _EM&_Enum&M. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- EN. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) +- _EN&_Enum&N. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.transformed.expect new file mode 100644 index 00000000000..d680f8ae884 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.strong.transformed.expect @@ -0,0 +1,128 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +abstract class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EA&_Enum&A extends core::_Enum implements self::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EA&_Enum&A + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EA extends self::_EA&_Enum&A /*isEnum*/ { + static const field core::List values = #C4; + static const field self::EA element = #C3; + const constructor •(core::int index, core::String name) → self::EA + : super self::_EA&_Enum&A::•(index, name) + ; + method toString() → core::String + ; +} +abstract class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EB&_Enum&B extends core::_Enum implements self::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EB&_Enum&B + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EB extends self::_EB&_Enum&B /*isEnum*/ { + static const field core::List values = #C6; + static const field self::EB element = #C5; + const constructor •(core::int index, core::String name) → self::EB + : super self::_EB&_Enum&B::•(index, name) + ; + method toString() → core::String + ; +} +abstract class M extends core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EM&_Enum&M extends core::_Enum implements self::M /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EM&_Enum&M + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EM extends self::_EM&_Enum&M /*isEnum*/ { + static const field core::List values = #C8; + static const field self::EM element = #C7; + const constructor •(core::int index, core::String name) → self::EM + : super self::_EM&_Enum&M::•(index, name) + ; + method toString() → core::String + ; +} +abstract class N extends core::Object implements core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EN&_Enum&N extends core::_Enum implements self::N /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EN&_Enum&N + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EN extends self::_EN&_Enum&N /*isEnum*/ { + static const field core::List values = #C10; + static const field self::EN element = #C9; + const constructor •(core::int index, core::String name) → self::EN + : super self::_EN&_Enum&N::•(index, name) + ; + method toString() → core::String + ; +} +static method expectEquals(dynamic x, dynamic y) → dynamic { + if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) { + throw "Expected '${x}' to be equal to '${y}'."; + } +} +static method main() → dynamic { + self::expectEquals(#C3.{self::_EA&_Enum&A::foo}{core::int}, #C3.{core::_Enum::index}{core::int}); + self::expectEquals(#C5.{self::_EB&_Enum&B::foo}{core::int}, #C5.{core::_Enum::index}{core::int}); + self::expectEquals(#C7.{self::_EM&_Enum&M::foo}{core::int}, #C7.{core::_Enum::index}{core::int}); + self::expectEquals(#C9.{self::_EN&_Enum&N::foo}{core::int}, #C9.{core::_Enum::index}{core::int}); +} + +constants { + #C1 = 0 + #C2 = "element" + #C3 = self::EA {index:#C1, _name:#C2} + #C4 = [#C3] + #C5 = self::EB {index:#C1, _name:#C2} + #C6 = [#C5] + #C7 = self::EM {index:#C1, _name:#C2} + #C8 = [#C7] + #C9 = self::EN {index:#C1, _name:#C2} + #C10 = [#C9] +} + + +Constructor coverage from constants: +org-dartlang-testcase:///enum_as_supertype.dart: +- EA. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _EA&_Enum&A. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9) +- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9) +- EB. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- _EB&_Enum&B. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- EM. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- _EM&_Enum&M. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- EN. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) +- _EN&_Enum&N. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.textual_outline.expect new file mode 100644 index 00000000000..43447504288 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.textual_outline.expect @@ -0,0 +1,18 @@ +abstract class A extends Enum { + int get foo => index; +} +enum EA with A { element } +abstract class B implements Enum { + int get foo => index; +} +enum EB with B { element } +mixin M on Enum { + int get foo => index; +} +enum EM with M { element } +mixin N implements Enum { + int get foo => index; +} +enum EN with N { element } +expectEquals(x, y) {} +main() {} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.expect new file mode 100644 index 00000000000..f8907f316f3 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.expect @@ -0,0 +1,128 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +abstract class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EA&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EA&_Enum&A + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::A::foo}; +} +class EA extends self::_EA&_Enum&A /*isEnum*/ { + static const field core::List values = #C4; + static const field self::EA element = #C3; + const constructor •(core::int index, core::String name) → self::EA + : super self::_EA&_Enum&A::•(index, name) + ; + method toString() → core::String + ; +} +abstract class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EB&_Enum&B = core::_Enum with self::B /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EB&_Enum&B + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::B::foo}; +} +class EB extends self::_EB&_Enum&B /*isEnum*/ { + static const field core::List values = #C6; + static const field self::EB element = #C5; + const constructor •(core::int index, core::String name) → self::EB + : super self::_EB&_Enum&B::•(index, name) + ; + method toString() → core::String + ; +} +abstract class M extends core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EM&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EM&_Enum&M + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::M::foo}; +} +class EM extends self::_EM&_Enum&M /*isEnum*/ { + static const field core::List values = #C8; + static const field self::EM element = #C7; + const constructor •(core::int index, core::String name) → self::EM + : super self::_EM&_Enum&M::•(index, name) + ; + method toString() → core::String + ; +} +abstract class N extends core::Object implements core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EN&_Enum&N = core::_Enum with self::N /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EN&_Enum&N + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::N::foo}; +} +class EN extends self::_EN&_Enum&N /*isEnum*/ { + static const field core::List values = #C10; + static const field self::EN element = #C9; + const constructor •(core::int index, core::String name) → self::EN + : super self::_EN&_Enum&N::•(index, name) + ; + method toString() → core::String + ; +} +static method expectEquals(dynamic x, dynamic y) → dynamic { + if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) { + throw "Expected '${x}' to be equal to '${y}'."; + } +} +static method main() → dynamic { + self::expectEquals(#C3.{self::_EA&_Enum&A::foo}{core::int}, #C3.{core::_Enum::index}{core::int}); + self::expectEquals(#C5.{self::_EB&_Enum&B::foo}{core::int}, #C5.{core::_Enum::index}{core::int}); + self::expectEquals(#C7.{self::_EM&_Enum&M::foo}{core::int}, #C7.{core::_Enum::index}{core::int}); + self::expectEquals(#C9.{self::_EN&_Enum&N::foo}{core::int}, #C9.{core::_Enum::index}{core::int}); +} + +constants { + #C1 = 0 + #C2 = "element" + #C3 = self::EA {index:#C1, _name:#C2} + #C4 = [#C3] + #C5 = self::EB {index:#C1, _name:#C2} + #C6 = [#C5] + #C7 = self::EM {index:#C1, _name:#C2} + #C8 = [#C7] + #C9 = self::EN {index:#C1, _name:#C2} + #C10 = [#C9] +} + + +Constructor coverage from constants: +org-dartlang-testcase:///enum_as_supertype.dart: +- EA. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _EA&_Enum&A. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9) +- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9) +- EB. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- _EB&_Enum&B. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- EM. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- _EM&_Enum&M. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- EN. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) +- _EN&_Enum&N. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.modular.expect new file mode 100644 index 00000000000..f8907f316f3 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.modular.expect @@ -0,0 +1,128 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +abstract class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EA&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EA&_Enum&A + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::A::foo}; +} +class EA extends self::_EA&_Enum&A /*isEnum*/ { + static const field core::List values = #C4; + static const field self::EA element = #C3; + const constructor •(core::int index, core::String name) → self::EA + : super self::_EA&_Enum&A::•(index, name) + ; + method toString() → core::String + ; +} +abstract class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EB&_Enum&B = core::_Enum with self::B /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EB&_Enum&B + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::B::foo}; +} +class EB extends self::_EB&_Enum&B /*isEnum*/ { + static const field core::List values = #C6; + static const field self::EB element = #C5; + const constructor •(core::int index, core::String name) → self::EB + : super self::_EB&_Enum&B::•(index, name) + ; + method toString() → core::String + ; +} +abstract class M extends core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EM&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EM&_Enum&M + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::M::foo}; +} +class EM extends self::_EM&_Enum&M /*isEnum*/ { + static const field core::List values = #C8; + static const field self::EM element = #C7; + const constructor •(core::int index, core::String name) → self::EM + : super self::_EM&_Enum&M::•(index, name) + ; + method toString() → core::String + ; +} +abstract class N extends core::Object implements core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EN&_Enum&N = core::_Enum with self::N /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EN&_Enum&N + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::N::foo}; +} +class EN extends self::_EN&_Enum&N /*isEnum*/ { + static const field core::List values = #C10; + static const field self::EN element = #C9; + const constructor •(core::int index, core::String name) → self::EN + : super self::_EN&_Enum&N::•(index, name) + ; + method toString() → core::String + ; +} +static method expectEquals(dynamic x, dynamic y) → dynamic { + if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) { + throw "Expected '${x}' to be equal to '${y}'."; + } +} +static method main() → dynamic { + self::expectEquals(#C3.{self::_EA&_Enum&A::foo}{core::int}, #C3.{core::_Enum::index}{core::int}); + self::expectEquals(#C5.{self::_EB&_Enum&B::foo}{core::int}, #C5.{core::_Enum::index}{core::int}); + self::expectEquals(#C7.{self::_EM&_Enum&M::foo}{core::int}, #C7.{core::_Enum::index}{core::int}); + self::expectEquals(#C9.{self::_EN&_Enum&N::foo}{core::int}, #C9.{core::_Enum::index}{core::int}); +} + +constants { + #C1 = 0 + #C2 = "element" + #C3 = self::EA {index:#C1, _name:#C2} + #C4 = [#C3] + #C5 = self::EB {index:#C1, _name:#C2} + #C6 = [#C5] + #C7 = self::EM {index:#C1, _name:#C2} + #C8 = [#C7] + #C9 = self::EN {index:#C1, _name:#C2} + #C10 = [#C9] +} + + +Constructor coverage from constants: +org-dartlang-testcase:///enum_as_supertype.dart: +- EA. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _EA&_Enum&A. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9) +- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9) +- EB. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- _EB&_Enum&B. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- EM. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- _EM&_Enum&M. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- EN. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) +- _EN&_Enum&N. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.outline.expect new file mode 100644 index 00000000000..dbfdd01c1b9 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.outline.expect @@ -0,0 +1,100 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +abstract class A extends core::Enum { + synthetic constructor •() → self::A + ; + get foo() → core::int + ; +} +abstract class _EA&_Enum&A = core::_Enum with self::A /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EA&_Enum&A + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::A::foo}; +} +class EA extends self::_EA&_Enum&A /*isEnum*/ { + static const field core::List values = const [self::EA::element]; + static const field self::EA element = const self::EA::•(0, "element"); + const constructor •(core::int index, core::String name) → self::EA + ; + method toString() → core::String + ; +} +abstract class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + ; + get foo() → core::int + ; +} +abstract class _EB&_Enum&B = core::_Enum with self::B /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EB&_Enum&B + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::B::foo}; +} +class EB extends self::_EB&_Enum&B /*isEnum*/ { + static const field core::List values = const [self::EB::element]; + static const field self::EB element = const self::EB::•(0, "element"); + const constructor •(core::int index, core::String name) → self::EB + ; + method toString() → core::String + ; +} +abstract class M extends core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + ; +} +abstract class _EM&_Enum&M = core::_Enum with self::M /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EM&_Enum&M + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::M::foo}; +} +class EM extends self::_EM&_Enum&M /*isEnum*/ { + static const field core::List values = const [self::EM::element]; + static const field self::EM element = const self::EM::•(0, "element"); + const constructor •(core::int index, core::String name) → self::EM + ; + method toString() → core::String + ; +} +abstract class N extends core::Object implements core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + ; +} +abstract class _EN&_Enum&N = core::_Enum with self::N /*isAnonymousMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EN&_Enum&N + : super core::_Enum::•(index, _name) + ; + mixin-super-stub get foo() → core::int + return super.{self::N::foo}; +} +class EN extends self::_EN&_Enum&N /*isEnum*/ { + static const field core::List values = const [self::EN::element]; + static const field self::EN element = const self::EN::•(0, "element"); + const constructor •(core::int index, core::String name) → self::EN + ; + method toString() → core::String + ; +} +static method expectEquals(dynamic x, dynamic y) → dynamic + ; +static method main() → dynamic + ; + + +Extra constant evaluation status: +Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype.dart:9:6 -> ListConstant(const [const EA{}]) +Evaluated: ConstructorInvocation @ org-dartlang-testcase:///enum_as_supertype.dart:9:18 -> InstanceConstant(const EA{}) +Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype.dart:15:6 -> ListConstant(const [const EB{}]) +Evaluated: ConstructorInvocation @ org-dartlang-testcase:///enum_as_supertype.dart:15:18 -> InstanceConstant(const EB{}) +Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype.dart:21:6 -> ListConstant(const [const EM{}]) +Evaluated: ConstructorInvocation @ org-dartlang-testcase:///enum_as_supertype.dart:21:18 -> InstanceConstant(const EM{}) +Evaluated: ListLiteral @ org-dartlang-testcase:///enum_as_supertype.dart:27:6 -> ListConstant(const [const EN{}]) +Evaluated: ConstructorInvocation @ org-dartlang-testcase:///enum_as_supertype.dart:27:18 -> InstanceConstant(const EN{}) +Extra constant evaluation: evaluated: 20, effectively constant: 8 diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.transformed.expect new file mode 100644 index 00000000000..4417c2ad552 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype.dart.weak.transformed.expect @@ -0,0 +1,128 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +abstract class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EA&_Enum&A extends core::_Enum implements self::A /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EA&_Enum&A + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EA extends self::_EA&_Enum&A /*isEnum*/ { + static const field core::List values = #C4; + static const field self::EA element = #C3; + const constructor •(core::int index, core::String name) → self::EA + : super self::_EA&_Enum&A::•(index, name) + ; + method toString() → core::String + ; +} +abstract class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EB&_Enum&B extends core::_Enum implements self::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EB&_Enum&B + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EB extends self::_EB&_Enum&B /*isEnum*/ { + static const field core::List values = #C6; + static const field self::EB element = #C5; + const constructor •(core::int index, core::String name) → self::EB + : super self::_EB&_Enum&B::•(index, name) + ; + method toString() → core::String + ; +} +abstract class M extends core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EM&_Enum&M extends core::_Enum implements self::M /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EM&_Enum&M + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EM extends self::_EM&_Enum&M /*isEnum*/ { + static const field core::List values = #C8; + static const field self::EM element = #C7; + const constructor •(core::int index, core::String name) → self::EM + : super self::_EM&_Enum&M::•(index, name) + ; + method toString() → core::String + ; +} +abstract class N extends core::Object implements core::Enum /*isMixinDeclaration*/ { + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +abstract class _EN&_Enum&N extends core::_Enum implements self::N /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ { + const synthetic constructor •(core::int index, core::String _name) → self::_EN&_Enum&N + : super core::_Enum::•(index, _name) + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; +} +class EN extends self::_EN&_Enum&N /*isEnum*/ { + static const field core::List values = #C10; + static const field self::EN element = #C9; + const constructor •(core::int index, core::String name) → self::EN + : super self::_EN&_Enum&N::•(index, name) + ; + method toString() → core::String + ; +} +static method expectEquals(dynamic x, dynamic y) → dynamic { + if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) { + throw "Expected '${x}' to be equal to '${y}'."; + } +} +static method main() → dynamic { + self::expectEquals(#C3.{self::_EA&_Enum&A::foo}{core::int}, #C3.{core::_Enum::index}{core::int}); + self::expectEquals(#C5.{self::_EB&_Enum&B::foo}{core::int}, #C5.{core::_Enum::index}{core::int}); + self::expectEquals(#C7.{self::_EM&_Enum&M::foo}{core::int}, #C7.{core::_Enum::index}{core::int}); + self::expectEquals(#C9.{self::_EN&_Enum&N::foo}{core::int}, #C9.{core::_Enum::index}{core::int}); +} + +constants { + #C1 = 0 + #C2 = "element" + #C3 = self::EA {index:#C1, _name:#C2} + #C4 = [#C3] + #C5 = self::EB {index:#C1, _name:#C2} + #C6 = [#C5] + #C7 = self::EM {index:#C1, _name:#C2} + #C8 = [#C7] + #C9 = self::EN {index:#C1, _name:#C2} + #C10 = [#C9] +} + + +Constructor coverage from constants: +org-dartlang-testcase:///enum_as_supertype.dart: +- EA. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _EA&_Enum&A. (from org-dartlang-testcase:///enum_as_supertype.dart:9:6) +- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9) +- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9) +- EB. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- _EB&_Enum&B. (from org-dartlang-testcase:///enum_as_supertype.dart:15:6) +- EM. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- _EM&_Enum&M. (from org-dartlang-testcase:///enum_as_supertype.dart:21:6) +- EN. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) +- _EN&_Enum&N. (from org-dartlang-testcase:///enum_as_supertype.dart:27:6) diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart new file mode 100644 index 00000000000..7d0f370f452 --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2022, 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. + +class A extends Enum { // Error. + int get foo => index; +} + +class B implements Enum { // Error. + int get foo => index; +} + +main() {} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect new file mode 100644 index 00000000000..8e7b23143fa --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.expect @@ -0,0 +1,69 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: Non-abstract class 'A' has 'Enum' as a superinterface. +// class A extends Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: Non-abstract class 'B' has 'Enum' as a superinterface. +// class B implements Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: The non-abstract class 'A' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class A extends Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: The non-abstract class 'B' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class B implements Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +static method main() → dynamic {} + +constants { + #C1 = #org-dartlang-testcase:///enum_as_supertype_error.dart::_name + #C2 = [] + #C3 = [] + #C4 = {) +} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect new file mode 100644 index 00000000000..8e7b23143fa --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.strong.transformed.expect @@ -0,0 +1,69 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: Non-abstract class 'A' has 'Enum' as a superinterface. +// class A extends Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: Non-abstract class 'B' has 'Enum' as a superinterface. +// class B implements Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: The non-abstract class 'A' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class A extends Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: The non-abstract class 'B' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class B implements Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +static method main() → dynamic {} + +constants { + #C1 = #org-dartlang-testcase:///enum_as_supertype_error.dart::_name + #C2 = [] + #C3 = [] + #C4 = {) +} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline.expect new file mode 100644 index 00000000000..585427e17fd --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline.expect @@ -0,0 +1,9 @@ +class A extends Enum { + int get foo => index; +} + +class B implements Enum { + int get foo => index; +} + +main() {} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..585427e17fd --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.textual_outline_modelled.expect @@ -0,0 +1,9 @@ +class A extends Enum { + int get foo => index; +} + +class B implements Enum { + int get foo => index; +} + +main() {} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect new file mode 100644 index 00000000000..8e7b23143fa --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.expect @@ -0,0 +1,69 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: Non-abstract class 'A' has 'Enum' as a superinterface. +// class A extends Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: Non-abstract class 'B' has 'Enum' as a superinterface. +// class B implements Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: The non-abstract class 'A' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class A extends Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: The non-abstract class 'B' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class B implements Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +static method main() → dynamic {} + +constants { + #C1 = #org-dartlang-testcase:///enum_as_supertype_error.dart::_name + #C2 = [] + #C3 = [] + #C4 = {) +} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect new file mode 100644 index 00000000000..8e7b23143fa --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.modular.expect @@ -0,0 +1,69 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: Non-abstract class 'A' has 'Enum' as a superinterface. +// class A extends Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: Non-abstract class 'B' has 'Enum' as a superinterface. +// class B implements Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: The non-abstract class 'A' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class A extends Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: The non-abstract class 'B' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class B implements Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +static method main() → dynamic {} + +constants { + #C1 = #org-dartlang-testcase:///enum_as_supertype_error.dart::_name + #C2 = [] + #C3 = [] + #C4 = {) +} diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect new file mode 100644 index 00000000000..08bae2fe95b --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.outline.expect @@ -0,0 +1,73 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: Non-abstract class 'A' has 'Enum' as a superinterface. +// class A extends Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: Non-abstract class 'B' has 'Enum' as a superinterface. +// class B implements Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: The non-abstract class 'A' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class A extends Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: The non-abstract class 'B' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class B implements Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Enum { + synthetic constructor •() → self::A + ; + get foo() → core::int + ; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_name, 1, const [], const [], core::Map::unmodifiable(const {}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + ; + get foo() → core::int + ; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_name, 1, const [], const [], core::Map::unmodifiable(const {}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +static method main() → dynamic + ; + + +Extra constant evaluation status: +Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> SymbolConstant(#_name) +Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const []) +Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const []) +Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> MapConstant(const {}) +Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> SymbolConstant(#_name) +Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const []) +Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> ListConstant(const []) +Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/core/enum.dart:47:14 -> MapConstant(const {}) +Extra constant evaluation: evaluated: 18, effectively constant: 8 diff --git a/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect new file mode 100644 index 00000000000..8e7b23143fa --- /dev/null +++ b/pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart.weak.transformed.expect @@ -0,0 +1,69 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: Non-abstract class 'A' has 'Enum' as a superinterface. +// class A extends Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: Non-abstract class 'B' has 'Enum' as a superinterface. +// class B implements Enum { // Error. +// ^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:5:7: Error: The non-abstract class 'A' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class A extends Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +// pkg/front_end/testcases/enhanced_enums/enum_as_supertype_error.dart:9:7: Error: The non-abstract class 'B' is missing implementations for these members: +// - Enum.index +// Try to either +// - provide an implementation, +// - inherit an implementation from a superclass or mixin, +// - mark the class as abstract, or +// - provide a 'noSuchMethod' implementation. +// +// class B implements Enum { // Error. +// ^ +// sdk/lib/core/enum.dart:22:11: Context: 'Enum.index' is defined here. +// int get index; +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Enum { + synthetic constructor •() → self::A + : super core::Enum::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +class B extends core::Object implements core::Enum { + synthetic constructor •() → self::B + : super core::Object::•() + ; + get foo() → core::int + return this.{core::Enum::index}{core::int}; + no-such-method-forwarder get /* from org-dartlang-sdk:///sdk/lib/core/enum.dart */ _name() → core::String + return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable(#C4))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String; +} +static method main() → dynamic {} + +constants { + #C1 = #org-dartlang-testcase:///enum_as_supertype_error.dart::_name + #C2 = [] + #C3 = [] + #C4 = {) +} diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status index f57bbdfd511..de5dad0a737 100644 --- a/pkg/front_end/testcases/strong.status +++ b/pkg/front_end/testcases/strong.status @@ -15,6 +15,7 @@ static_field_lowering/opt_in: SemiFuzzFailure constructor_tearoffs/call_instantiation: TypeCheckError constructor_tearoffs/lowering/invalid_redirect: VerificationError +enhanced_enums/enum_as_supertype: RuntimeError enhanced_enums/simple_mixins: RuntimeError extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected. extension_types/call_not_get: ExpectationFileMismatchSerialized # Expected. diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status index 5a838fad832..3630e3a1f62 100644 --- a/pkg/front_end/testcases/text_serialization.status +++ b/pkg/front_end/testcases/text_serialization.status @@ -8,6 +8,7 @@ constructor_tearoffs/call_instantiation: TypeCheckError constructor_tearoffs/lowering/invalid_redirect: VerificationError +enhanced_enums/enum_as_supertype: RuntimeError enhanced_enums/simple_mixins: RuntimeError extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected. extension_types/call_not_get: ExpectationFileMismatchSerialized # Expected. diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status index 08951212d0a..19957426e3d 100644 --- a/pkg/front_end/testcases/textual_outline.status +++ b/pkg/front_end/testcases/textual_outline.status @@ -29,6 +29,7 @@ constructor_tearoffs/new_as_selector: FormatterCrash dart2js/late_fields: FormatterCrash dart2js/late_statics: FormatterCrash enhanced_enums/entries_with_type_arguments: FormatterCrash +enhanced_enums/enum_as_supertype: FormatterCrash enhanced_enums/inference_in_constructor_parameters: FormatterCrash enhanced_enums/instantiated_generic_enum_types: FormatterCrash enhanced_enums/issue48084: FormatterCrash diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status index f75594a50ec..c71436cad47 100644 --- a/pkg/front_end/testcases/weak.status +++ b/pkg/front_end/testcases/weak.status @@ -22,6 +22,7 @@ static_field_lowering/opt_in: SemiFuzzFailure constructor_tearoffs/call_instantiation: TypeCheckError constructor_tearoffs/lowering/invalid_redirect: VerificationError +enhanced_enums/enum_as_supertype: RuntimeError enhanced_enums/simple_mixins: RuntimeError extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected. extension_types/call_not_get: ExpectationFileMismatchSerialized # Expected.