[cfe] Adjust the parameter number for enum constructors

Closes https://github.com/dart-lang/sdk/issues/49216

Change-Id: Id3ad8f10632fc87075fef45f2f60b21016ade20f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247965
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index 43b3074..00b7e5e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -47,6 +47,7 @@
         noLength;
 import '../scope.dart';
 import '../source/source_class_builder.dart';
+import '../source/source_enum_builder.dart';
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 import '../source/source_loader.dart' show SourceLoader;
 import '../source/source_member_builder.dart';
@@ -249,6 +250,15 @@
   }
 
   @override
+  VariableDeclaration getFormalParameter(int index) {
+    if (parent is SourceEnumBuilder) {
+      return formals![index + 2].variable!;
+    } else {
+      return super.getFormalParameter(index);
+    }
+  }
+
+  @override
   void inferTypes(ClassHierarchyBase hierarchy) {
     inferFormalTypes(hierarchy);
   }
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect
index beb0d94..c6b555c 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.expect
@@ -8,7 +8,7 @@
   final field core::int bar;
   static const field self::E0 one = #C4;
   static const field self::E0 two = #C7;
-  const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+  const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
     : self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -19,7 +19,7 @@
   final field self::E1::X% foo;
   static const field self::E1<core::String> one = #C11;
   static const field self::E1<core::int> two = #C12;
-  const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+  const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
     : self::E1::foo = foo, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -33,7 +33,7 @@
   static const field self::E2<core::int, core::String, core::double> one = #C15;
   static const field self::E2<core::String, core::int, core::double> two = #C17;
   static const field self::E2<core::double, core::bool, dynamic> three = #C21;
-  const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+  const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
     : self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect
index beb0d94..c6b555c 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
   final field core::int bar;
   static const field self::E0 one = #C4;
   static const field self::E0 two = #C7;
-  const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+  const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
     : self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -19,7 +19,7 @@
   final field self::E1::X% foo;
   static const field self::E1<core::String> one = #C11;
   static const field self::E1<core::int> two = #C12;
-  const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+  const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
     : self::E1::foo = foo, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -33,7 +33,7 @@
   static const field self::E2<core::int, core::String, core::double> one = #C15;
   static const field self::E2<core::String, core::int, core::double> two = #C17;
   static const field self::E2<core::double, core::bool, dynamic> three = #C21;
-  const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+  const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
     : self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect
index 67cb833..04b9df2 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.expect
@@ -8,7 +8,7 @@
   final field core::int bar;
   static const field self::E0 one = #C4;
   static const field self::E0 two = #C7;
-  const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+  const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
     : self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -19,7 +19,7 @@
   final field self::E1::X% foo;
   static const field self::E1<core::String> one = #C11;
   static const field self::E1<core::int> two = #C12;
-  const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+  const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
     : self::E1::foo = foo, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -33,7 +33,7 @@
   static const field self::E2<core::int, core::String, core::double> one = #C15;
   static const field self::E2<core::String, core::int, core::double> two = #C17;
   static const field self::E2<core::double, core::bool, dynamic> three = #C21;
-  const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+  const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
     : self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect
index 67cb833..04b9df2 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.modular.expect
@@ -8,7 +8,7 @@
   final field core::int bar;
   static const field self::E0 one = #C4;
   static const field self::E0 two = #C7;
-  const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+  const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
     : self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -19,7 +19,7 @@
   final field self::E1::X% foo;
   static const field self::E1<core::String> one = #C11;
   static const field self::E1<core::int> two = #C12;
-  const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+  const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
     : self::E1::foo = foo, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -33,7 +33,7 @@
   static const field self::E2<core::int, core::String, core::double> one = #C15;
   static const field self::E2<core::String, core::int, core::double> two = #C17;
   static const field self::E2<core::double, core::bool, dynamic> three = #C21;
-  const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+  const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
     : self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
diff --git a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect
index 67cb833..04b9df2 100644
--- a/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/named_arguments.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
   final field core::int bar;
   static const field self::E0 one = #C4;
   static const field self::E0 two = #C7;
-  const constructor •(core::int #index, core::String #name = #C9, core::int foo, {required core::int bar = #C9}) → self::E0
+  const constructor •(core::int #index, core::String #name, core::int foo, {required core::int bar = #C9}) → self::E0
     : self::E0::foo = foo, self::E0::bar = bar, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -19,7 +19,7 @@
   final field self::E1::X% foo;
   static const field self::E1<core::String> one = #C11;
   static const field self::E1<core::int> two = #C12;
-  const constructor •(core::int #index = #C9, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
+  const constructor •(core::int #index, core::String #name, {required self::E1::X% foo = #C9}) → self::E1<self::E1::X%>
     : self::E1::foo = foo, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
@@ -33,7 +33,7 @@
   static const field self::E2<core::int, core::String, core::double> one = #C15;
   static const field self::E2<core::String, core::int, core::double> two = #C17;
   static const field self::E2<core::double, core::bool, dynamic> three = #C21;
-  const constructor •(core::int #index, core::String #name = #C9, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
+  const constructor •(core::int #index, core::String #name, self::E2::X% foo, {required self::E2::Y% bar = #C9, has-declared-initializer self::E2::Z? baz = #C9}) → self::E2<self::E2::X%, self::E2::Y%, self::E2::Z%>
     : self::E2::foo = foo, self::E2::bar = bar, self::E2::baz = baz, super core::_Enum::•(#index, #name)
     ;
   method toString() → core::String
diff --git a/pkg/front_end/testcases/general/issue49216.dart b/pkg/front_end/testcases/general/issue49216.dart
new file mode 100644
index 0000000..1668ed4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart
@@ -0,0 +1,12 @@
+// 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.
+
+enum E {
+  foo;
+
+  const E([int x = 0, String y = "", num? z]);
+  const E.named(int x, {String y = "", bool b = false, String? z, bool? t});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49216.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49216.dart.textual_outline.expect
new file mode 100644
index 0000000..d4f3d20
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+enum E {
+  foo;
+
+  const E([int x = 0, String y = "", num? z]);
+  const E.named(int x, {String y = "", bool b = false, String? z, bool? t});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49216.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49216.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d4f3d20
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+enum E {
+  foo;
+
+  const E([int x = 0, String y = "", num? z]);
+  const E.named(int x, {String y = "", bool b = false, String? z, bool? t});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.expect
new file mode 100644
index 0000000..eee9a44
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/  {
+  static const field core::List<self::E> values = #C4;
+  static const field self::E foo = #C3;
+  const constructor •(core::int #index, core::String #name, [core::int x = #C1, core::String y = #C5, core::num? z = #C6]) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  const constructor named(core::int #index, core::String #name, core::int x, {core::String y = #C5, core::bool b = #C7, core::String? z = #C6, core::bool? t = #C6}) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  method toString() → core::String
+    return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = 0
+  #C2 = "foo"
+  #C3 = self::E {index:#C1, _name:#C2}
+  #C4 = <self::E*>[#C3]
+  #C5 = ""
+  #C6 = null
+  #C7 = false
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49216.dart:
+- E. (from org-dartlang-testcase:///issue49216.dart:8:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.modular.expect
new file mode 100644
index 0000000..eee9a44
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.modular.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/  {
+  static const field core::List<self::E> values = #C4;
+  static const field self::E foo = #C3;
+  const constructor •(core::int #index, core::String #name, [core::int x = #C1, core::String y = #C5, core::num? z = #C6]) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  const constructor named(core::int #index, core::String #name, core::int x, {core::String y = #C5, core::bool b = #C7, core::String? z = #C6, core::bool? t = #C6}) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  method toString() → core::String
+    return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = 0
+  #C2 = "foo"
+  #C3 = self::E {index:#C1, _name:#C2}
+  #C4 = <self::E*>[#C3]
+  #C5 = ""
+  #C6 = null
+  #C7 = false
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49216.dart:
+- E. (from org-dartlang-testcase:///issue49216.dart:8:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.outline.expect
new file mode 100644
index 0000000..fa29e74
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.outline.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/  {
+  static const field core::List<self::E> values = const <self::E>[self::E::foo];
+  static const field self::E foo = const self::E::•(0, "foo");
+  const constructor •(core::int #index, core::String #name, [core::int x = 0, core::String y = "", core::num? z = null]) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  const constructor named(core::int #index, core::String #name, core::int x, {core::String y = "", core::bool b = false, core::String? z = null, core::bool? t = null}) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  method toString() → core::String
+    return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///issue49216.dart:5:6 -> ListConstant(const <E*>[const E{_Enum.index: 0, _Enum._name: "foo"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue49216.dart:6:3 -> InstanceConstant(const E{_Enum.index: 0, _Enum._name: "foo"})
+Extra constant evaluation: evaluated: 9, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/issue49216.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49216.dart.weak.transformed.expect
new file mode 100644
index 0000000..eee9a44
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49216.dart.weak.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::_Enum /*isEnum*/  {
+  static const field core::List<self::E> values = #C4;
+  static const field self::E foo = #C3;
+  const constructor •(core::int #index, core::String #name, [core::int x = #C1, core::String y = #C5, core::num? z = #C6]) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  const constructor named(core::int #index, core::String #name, core::int x, {core::String y = #C5, core::bool b = #C7, core::String? z = #C6, core::bool? t = #C6}) → self::E
+    : super core::_Enum::•(#index, #name)
+    ;
+  method toString() → core::String
+    return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = 0
+  #C2 = "foo"
+  #C3 = self::E {index:#C1, _name:#C2}
+  #C4 = <self::E*>[#C3]
+  #C5 = ""
+  #C6 = null
+  #C7 = false
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue49216.dart:
+- E. (from org-dartlang-testcase:///issue49216.dart:8:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:103:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)