[cfe] Handle required parameters in combined member signature creation
Change-Id: I4ee6a6f1f404a65e7abc926adaa08178698838e9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170880
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index ea003a5..f89b4e8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -582,18 +582,22 @@
NamedType namedType = functionType.namedParameters.first;
VariableDeclaration parameter = function.namedParameters.first;
namedParameters.add(new VariableDeclaration(parameter.name,
- type: namedType.type, isCovariant: parameter.isCovariant)
+ type: namedType.type,
+ isRequired: namedType.isRequired,
+ isCovariant: parameter.isCovariant)
..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
} else if (namedParameterCount > 1) {
- Map<String, DartType> namedTypes = {};
+ Map<String, NamedType> namedTypes = {};
for (NamedType namedType in functionType.namedParameters) {
- namedTypes[namedType.name] = namedType.type;
+ namedTypes[namedType.name] = namedType;
}
for (int i = 0; i < namedParameterCount; i++) {
VariableDeclaration parameter = function.namedParameters[i];
- DartType parameterType = namedTypes[parameter.name];
+ NamedType namedParameterType = namedTypes[parameter.name];
namedParameters.add(new VariableDeclaration(parameter.name,
- type: parameterType, isCovariant: parameter.isCovariant)
+ type: namedParameterType.type,
+ isRequired: namedParameterType.isRequired,
+ isCovariant: parameter.isCovariant)
..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
}
}
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart b/pkg/front_end/testcases/nnbd/combined_required.dart
new file mode 100644
index 0000000..9584091
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart
@@ -0,0 +1,18 @@
+class A {
+ void method1({required int a}) {}
+ void method2({int? a, required int b}) {}
+}
+
+class B {
+ void method1({required covariant int a}) {}
+ void method2({covariant int? a, required int b}) {}
+}
+
+class C extends A implements B {}
+
+class D extends C {
+ void method1({required covariant int a}) {}
+ void method2({covariant int? a, required int b}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart.outline.expect b/pkg/front_end/testcases/nnbd/combined_required.dart.outline.expect
new file mode 100644
index 0000000..f39bdf2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart.outline.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method method1({required core::int a}) → void
+ ;
+ method method2({core::int? a, required core::int b}) → void
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ ;
+ method method1({required covariant core::int a}) → void
+ ;
+ method method2({covariant core::int? a, required core::int b}) → void
+ ;
+}
+class C extends self::A implements self::B {
+ synthetic constructor •() → self::C
+ ;
+ forwarding-stub method method1({required covariant core::int a}) → void
+ return super.{self::A::method1}(a: a);
+ forwarding-stub method method2({covariant core::int? a, required core::int b}) → void
+ return super.{self::A::method2}(a: a, b: b);
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ ;
+ method method1({required covariant core::int a}) → void
+ ;
+ method method2({covariant core::int? a, required core::int b}) → void
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart.strong.expect b/pkg/front_end/testcases/nnbd/combined_required.dart.strong.expect
new file mode 100644
index 0000000..34958ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart.strong.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method method1({required core::int a = #C1}) → void {}
+ method method2({core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class C extends self::A implements self::B {
+ synthetic constructor •() → self::C
+ : super self::A::•()
+ ;
+ forwarding-stub method method1({required covariant core::int a = #C1}) → void
+ return super.{self::A::method1}(a: a);
+ forwarding-stub method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void
+ return super.{self::A::method2}(a: a, b: b);
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/combined_required.dart.strong.transformed.expect
new file mode 100644
index 0000000..34958ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method method1({required core::int a = #C1}) → void {}
+ method method2({core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class C extends self::A implements self::B {
+ synthetic constructor •() → self::C
+ : super self::A::•()
+ ;
+ forwarding-stub method method1({required covariant core::int a = #C1}) → void
+ return super.{self::A::method1}(a: a);
+ forwarding-stub method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void
+ return super.{self::A::method2}(a: a, b: b);
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/combined_required.dart.textual_outline.expect
new file mode 100644
index 0000000..9584091
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A {
+ void method1({required int a}) {}
+ void method2({int? a, required int b}) {}
+}
+
+class B {
+ void method1({required covariant int a}) {}
+ void method2({covariant int? a, required int b}) {}
+}
+
+class C extends A implements B {}
+
+class D extends C {
+ void method1({required covariant int a}) {}
+ void method2({covariant int? a, required int b}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/combined_required.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9584091
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class A {
+ void method1({required int a}) {}
+ void method2({int? a, required int b}) {}
+}
+
+class B {
+ void method1({required covariant int a}) {}
+ void method2({covariant int? a, required int b}) {}
+}
+
+class C extends A implements B {}
+
+class D extends C {
+ void method1({required covariant int a}) {}
+ void method2({covariant int? a, required int b}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart.weak.expect b/pkg/front_end/testcases/nnbd/combined_required.dart.weak.expect
new file mode 100644
index 0000000..34958ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart.weak.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method method1({required core::int a = #C1}) → void {}
+ method method2({core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class C extends self::A implements self::B {
+ synthetic constructor •() → self::C
+ : super self::A::•()
+ ;
+ forwarding-stub method method1({required covariant core::int a = #C1}) → void
+ return super.{self::A::method1}(a: a);
+ forwarding-stub method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void
+ return super.{self::A::method2}(a: a, b: b);
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/nnbd/combined_required.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/combined_required.dart.weak.transformed.expect
new file mode 100644
index 0000000..34958ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/combined_required.dart.weak.transformed.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method method1({required core::int a = #C1}) → void {}
+ method method2({core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+class C extends self::A implements self::B {
+ synthetic constructor •() → self::C
+ : super self::A::•()
+ ;
+ forwarding-stub method method1({required covariant core::int a = #C1}) → void
+ return super.{self::A::method1}(a: a);
+ forwarding-stub method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void
+ return super.{self::A::method2}(a: a, b: b);
+}
+class D extends self::C {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ method method1({required covariant core::int a = #C1}) → void {}
+ method method2({covariant core::int? a = #C1, required core::int b = #C1}) → void {}
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+}