From 0476748b123a9902cc8b1c4b2a78b770672ca2da Mon Sep 17 00:00:00 2001 From: Kallen Tu Date: Wed, 18 Mar 2026 09:35:30 -0700 Subject: [PATCH] [cfe] Dot shorthands - Resolve missing types from nested dot shorthands in other libraries. We were missing an `ensureMemberType` call before computing the function type. This caused some types to still be unresolved and create incorrect types for dot shorthand look ups. Tests (they go through all changed code paths) - Same library and different library - Extension type constructors - Normal constructors - Redirecting factory constructors - Static methods. Bug: https://github.com/dart-lang/sdk/issues/62877 Change-Id: I31871bf7bc97a1712b9b40459aa64220bfbaabe5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488580 Reviewed-by: Chloe Stefantsova Commit-Queue: Kallen Tu --- .../src/type_inference/inference_visitor.dart | 3 ++ .../dot_shorthands/nested_arguments.dart | 21 +++++++++ .../nested_arguments.dart.strong.expect | 22 ++++++++++ ...ested_arguments.dart.strong.modular.expect | 22 ++++++++++ ...ested_arguments.dart.strong.outline.expect | 21 +++++++++ ...d_arguments.dart.strong.transformed.expect | 22 ++++++++++ ...sted_arguments.dart.textual_outline.expect | 15 +++++++ ...ments.dart.textual_outline_modelled.expect | 15 +++++++ .../dot_shorthands/nested_arguments/main.dart | 13 ++++++ .../nested_arguments/main.dart.strong.expect | 30 +++++++++++++ .../main.dart.strong.modular.expect | 30 +++++++++++++ .../main.dart.strong.outline.expect | 29 ++++++++++++ .../main.dart.strong.transformed.expect | 30 +++++++++++++ .../main.dart.textual_outline.expect | 8 ++++ .../main.dart.textual_outline_modelled.expect | 8 ++++ .../nested_arguments/main_lib.dart | 13 ++++++ .../nested_arguments_extension_type.dart | 18 ++++++++ ...rguments_extension_type.dart.strong.expect | 36 +++++++++++++++ ..._extension_type.dart.strong.modular.expect | 36 +++++++++++++++ ..._extension_type.dart.strong.outline.expect | 30 +++++++++++++ ...ension_type.dart.strong.transformed.expect | 36 +++++++++++++++ ...extension_type.dart.textual_outline.expect | 14 ++++++ ..._type.dart.textual_outline_modelled.expect | 14 ++++++ .../nested_arguments_extension_type/main.dart | 13 ++++++ .../main.dart.strong.expect | 44 +++++++++++++++++++ .../main.dart.strong.modular.expect | 44 +++++++++++++++++++ .../main.dart.strong.outline.expect | 37 ++++++++++++++++ .../main.dart.strong.transformed.expect | 44 +++++++++++++++++++ .../main.dart.textual_outline.expect | 8 ++++ .../main.dart.textual_outline_modelled.expect | 8 ++++ .../main_lib.dart | 11 +++++ .../nested_arguments_redirecting_factory.dart | 21 +++++++++ ...nts_redirecting_factory.dart.strong.expect | 24 ++++++++++ ...recting_factory.dart.strong.modular.expect | 24 ++++++++++ ...recting_factory.dart.strong.outline.expect | 23 ++++++++++ ...ing_factory.dart.strong.transformed.expect | 24 ++++++++++ ...ecting_factory.dart.textual_outline.expect | 16 +++++++ ...ctory.dart.textual_outline_modelled.expect | 16 +++++++ .../main.dart | 13 ++++++ .../main.dart.strong.expect | 32 ++++++++++++++ .../main.dart.strong.modular.expect | 32 ++++++++++++++ .../main.dart.strong.outline.expect | 31 +++++++++++++ .../main.dart.strong.transformed.expect | 32 ++++++++++++++ .../main.dart.textual_outline.expect | 8 ++++ .../main.dart.textual_outline_modelled.expect | 8 ++++ .../main_lib.dart | 14 ++++++ .../nested_arguments_static_method.dart | 21 +++++++++ ...arguments_static_method.dart.strong.expect | 24 ++++++++++ ...s_static_method.dart.strong.modular.expect | 24 ++++++++++ ...s_static_method.dart.strong.outline.expect | 23 ++++++++++ ...atic_method.dart.strong.transformed.expect | 24 ++++++++++ ..._static_method.dart.textual_outline.expect | 16 +++++++ ...ethod.dart.textual_outline_modelled.expect | 16 +++++++ .../nested_arguments_static_method/main.dart | 13 ++++++ .../main.dart.strong.expect | 32 ++++++++++++++ .../main.dart.strong.modular.expect | 32 ++++++++++++++ .../main.dart.strong.outline.expect | 31 +++++++++++++ .../main.dart.strong.transformed.expect | 32 ++++++++++++++ .../main.dart.textual_outline.expect | 8 ++++ .../main.dart.textual_outline_modelled.expect | 8 ++++ .../main_lib.dart | 14 ++++++ 61 files changed, 1331 insertions(+) create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments/main_lib.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main_lib.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main_lib.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main_lib.dart diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/type_inference/inference_visitor.dart index c2aab4f2ea7..2fba1fb7a8c 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart @@ -16745,6 +16745,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase if (member is Procedure && member.kind == ProcedureKind.Method) { // The shorthand expression is inferred in the empty context and then type // inference infers the type arguments. + ensureMemberType(member); FunctionType functionType = member.function.computeThisFunctionType( Nullability.nonNullable, ); @@ -16827,6 +16828,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase // The shorthand expression is inferred in the empty context and then // type inference infers the type arguments. + ensureMemberType(constructor); FunctionType functionType = constructor.function .computeThisFunctionType(Nullability.nonNullable); InvocationInferenceResult result = inferInvocation( @@ -16872,6 +16874,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase // The shorthand expression is inferred in the empty context and then // type inference infers the type arguments. + ensureMemberType(constructor); FunctionType functionType = constructor.function .computeThisFunctionType(Nullability.nonNullable); InvocationInferenceResult result = inferInvocation( diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart new file mode 100644 index 00000000000..1c4cd2ae004 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2026, 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. + +final a = A(b: .new(c: .f(0))); + +class A { + final B b; + + const A({required this.b}); +} + +class B { + final C c; + + const B({required this.c}); +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.expect new file mode 100644 index 00000000000..41de890a51a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.expect @@ -0,0 +1,22 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new self::B::•(c: new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.modular.expect new file mode 100644 index 00000000000..41de890a51a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.modular.expect @@ -0,0 +1,22 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new self::B::•(c: new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.outline.expect new file mode 100644 index 00000000000..4534a9b1339 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.outline.expect @@ -0,0 +1,21 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + ; +} +static final field self::A a; diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.transformed.expect new file mode 100644 index 00000000000..41de890a51a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.strong.transformed.expect @@ -0,0 +1,22 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new self::B::•(c: new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline.expect new file mode 100644 index 00000000000..62f05c17d69 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline.expect @@ -0,0 +1,15 @@ +final a = A(b: .new(c: .f(0))); + +class A { + final B b; + const A({required this.b}); +} + +class B { + final C c; + const B({required this.c}); +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..e479076dfbc --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments.dart.textual_outline_modelled.expect @@ -0,0 +1,15 @@ +class A { + const A({required this.b}); + final B b; +} + +class B { + const B({required this.c}); + final C c; +} + +class C { + C.f(num n); +} + +final a = A(b: .new(c: .f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart new file mode 100644 index 00000000000..29d3bb8d696 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2026, 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. + +import 'main_lib.dart'; + +final a = A(b: .new(c: .f(0))); + +class A { + final B b; + + const A({required this.b}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.expect new file mode 100644 index 00000000000..18ca87ad777 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.expect @@ -0,0 +1,30 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new mai::B::•(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.modular.expect new file mode 100644 index 00000000000..18ca87ad777 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.modular.expect @@ -0,0 +1,30 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new mai::B::•(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.outline.expect new file mode 100644 index 00000000000..c19a1a464ab --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.outline.expect @@ -0,0 +1,29 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a; + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → mai::C + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.transformed.expect new file mode 100644 index 00000000000..18ca87ad777 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.strong.transformed.expect @@ -0,0 +1,30 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new mai::B::•(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline.expect new file mode 100644 index 00000000000..53a5bfb3bf4 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +final a = A(b: .new(c: .f(0))); + +class A { + final B b; + const A({required this.b}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..ba6709b87fb --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main.dart.textual_outline_modelled.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +class A { + const A({required this.b}); + final B b; +} + +final a = A(b: .new(c: .f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments/main_lib.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main_lib.dart new file mode 100644 index 00000000000..9de7bf0e251 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments/main_lib.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2026, 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 B { + final C c; + + const B({required this.c}); +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart new file mode 100644 index 00000000000..fe194d3dde3 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2026, 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. + +final a = A(bExt: .f(c: .f(0))); + +class A { + final BExt bExt; + const A({required this.bExt}); +} + +class C { + C.f(num n); +} + +extension type BExt(C c) { + BExt.f({required C c}) : this(c); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.expect new file mode 100644 index 00000000000..429a400b9da --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::BExt% /* erasure=self::C, declared=! */ bExt; + const constructor •({required self::BExt% /* erasure=self::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +extension type BExt(self::C c) { + abstract extension-type-member representation-field get c() → self::C; + constructor • = self::BExt|constructor#; + constructor tearoff • = self::BExt|constructor#_#new#tearOff; + constructor f = self::BExt|constructor#f; + constructor tearoff f = self::BExt|constructor#_#f#tearOff; +} +static final field self::A a = new self::A::•(bExt: self::BExt|constructor#f(c: new self::C::f(0))); +static extension-type-member method BExt|constructor#(self::C c) → self::BExt% /* erasure=self::C, declared=! */ { + lowered final self::BExt% /* erasure=self::C, declared=! */ #this = c; + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(self::C c) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ { + lowered final self::BExt% /* erasure=self::C, declared=! */ #this; + #this = self::BExt|constructor#(c); + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.modular.expect new file mode 100644 index 00000000000..429a400b9da --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.modular.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::BExt% /* erasure=self::C, declared=! */ bExt; + const constructor •({required self::BExt% /* erasure=self::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +extension type BExt(self::C c) { + abstract extension-type-member representation-field get c() → self::C; + constructor • = self::BExt|constructor#; + constructor tearoff • = self::BExt|constructor#_#new#tearOff; + constructor f = self::BExt|constructor#f; + constructor tearoff f = self::BExt|constructor#_#f#tearOff; +} +static final field self::A a = new self::A::•(bExt: self::BExt|constructor#f(c: new self::C::f(0))); +static extension-type-member method BExt|constructor#(self::C c) → self::BExt% /* erasure=self::C, declared=! */ { + lowered final self::BExt% /* erasure=self::C, declared=! */ #this = c; + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(self::C c) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ { + lowered final self::BExt% /* erasure=self::C, declared=! */ #this; + #this = self::BExt|constructor#(c); + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.outline.expect new file mode 100644 index 00000000000..b49e1069963 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.outline.expect @@ -0,0 +1,30 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::BExt% /* erasure=self::C, declared=! */ bExt; + const constructor •({required self::BExt% /* erasure=self::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + ; +} +extension type BExt(self::C c) { + abstract extension-type-member representation-field get c() → self::C; + constructor • = self::BExt|constructor#; + constructor tearoff • = self::BExt|constructor#_#new#tearOff; + constructor f = self::BExt|constructor#f; + constructor tearoff f = self::BExt|constructor#_#f#tearOff; +} +static final field self::A a; +static extension-type-member method BExt|constructor#(self::C c) → self::BExt% /* erasure=self::C, declared=! */ + ; +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(self::C c) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ + ; +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.transformed.expect new file mode 100644 index 00000000000..429a400b9da --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.strong.transformed.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::BExt% /* erasure=self::C, declared=! */ bExt; + const constructor •({required self::BExt% /* erasure=self::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +extension type BExt(self::C c) { + abstract extension-type-member representation-field get c() → self::C; + constructor • = self::BExt|constructor#; + constructor tearoff • = self::BExt|constructor#_#new#tearOff; + constructor f = self::BExt|constructor#f; + constructor tearoff f = self::BExt|constructor#_#f#tearOff; +} +static final field self::A a = new self::A::•(bExt: self::BExt|constructor#f(c: new self::C::f(0))); +static extension-type-member method BExt|constructor#(self::C c) → self::BExt% /* erasure=self::C, declared=! */ { + lowered final self::BExt% /* erasure=self::C, declared=! */ #this = c; + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(self::C c) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ { + lowered final self::BExt% /* erasure=self::C, declared=! */ #this; + #this = self::BExt|constructor#(c); + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required self::C c}) → self::BExt% /* erasure=self::C, declared=! */ + return self::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline.expect new file mode 100644 index 00000000000..27c2e7001ee --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline.expect @@ -0,0 +1,14 @@ +final a = A(bExt: .f(c: .f(0))); + +class A { + final BExt bExt; + const A({required this.bExt}); +} + +class C { + C.f(num n); +} + +extension type BExt(C c) { + BExt.f({required C c}) : this(c); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..0f59a8f9239 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type.dart.textual_outline_modelled.expect @@ -0,0 +1,14 @@ +class A { + const A({required this.bExt}); + final BExt bExt; +} + +class C { + C.f(num n); +} + +extension type BExt(C c) { + BExt.f({required C c}) : this(c); +} + +final a = A(bExt: .f(c: .f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart new file mode 100644 index 00000000000..b7a7362b4fe --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2026, 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. + +import 'main_lib.dart'; + +final a = A(bExt: .f(c: .f(0))); + +class A { + final BExt bExt; + + const A({required this.bExt}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.expect new file mode 100644 index 00000000000..9d2bbe42bcb --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.expect @@ -0,0 +1,44 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::BExt% /* erasure=mai::C, declared=! */ bExt; + const constructor •({required mai::BExt% /* erasure=mai::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(bExt: mai::BExt|constructor#f(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} +extension type BExt(mai::C c) { + abstract extension-type-member representation-field get c() → mai::C; + constructor • = mai::BExt|constructor#; + constructor tearoff • = mai::BExt|constructor#_#new#tearOff; + constructor f = mai::BExt|constructor#f; + constructor tearoff f = mai::BExt|constructor#_#f#tearOff; +} +static extension-type-member method BExt|constructor#(mai::C c) → mai::BExt% /* erasure=mai::C, declared=! */ { + lowered final mai::BExt% /* erasure=mai::C, declared=! */ #this = c; + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(mai::C c) → mai::BExt% /* erasure=mai::C, declared=! */ + return mai::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required mai::C c}) → mai::BExt% /* erasure=mai::C, declared=! */ { + lowered final mai::BExt% /* erasure=mai::C, declared=! */ #this; + #this = mai::BExt|constructor#(c); + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required mai::C c}) → mai::BExt% /* erasure=mai::C, declared=! */ + return mai::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.modular.expect new file mode 100644 index 00000000000..9d2bbe42bcb --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.modular.expect @@ -0,0 +1,44 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::BExt% /* erasure=mai::C, declared=! */ bExt; + const constructor •({required mai::BExt% /* erasure=mai::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(bExt: mai::BExt|constructor#f(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} +extension type BExt(mai::C c) { + abstract extension-type-member representation-field get c() → mai::C; + constructor • = mai::BExt|constructor#; + constructor tearoff • = mai::BExt|constructor#_#new#tearOff; + constructor f = mai::BExt|constructor#f; + constructor tearoff f = mai::BExt|constructor#_#f#tearOff; +} +static extension-type-member method BExt|constructor#(mai::C c) → mai::BExt% /* erasure=mai::C, declared=! */ { + lowered final mai::BExt% /* erasure=mai::C, declared=! */ #this = c; + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(mai::C c) → mai::BExt% /* erasure=mai::C, declared=! */ + return mai::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required mai::C c}) → mai::BExt% /* erasure=mai::C, declared=! */ { + lowered final mai::BExt% /* erasure=mai::C, declared=! */ #this; + #this = mai::BExt|constructor#(c); + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required mai::C c}) → mai::BExt% /* erasure=mai::C, declared=! */ + return mai::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.outline.expect new file mode 100644 index 00000000000..395f04f8d70 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.outline.expect @@ -0,0 +1,37 @@ +library; +import self as self; +import "dart:core" as core; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field #lib1::BExt% /* erasure=#lib1::C, declared=! */ bExt; + const constructor •({required #lib1::BExt% /* erasure=#lib1::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +static final field self::A a; + +library; +import self as self2; +import "dart:core" as core; + +class C extends core::Object { + constructor f(core::num n) → self2::C + ; +} +extension type BExt(self2::C c) { + abstract extension-type-member representation-field get c() → self2::C; + constructor • = self2::BExt|constructor#; + constructor tearoff • = self2::BExt|constructor#_#new#tearOff; + constructor f = self2::BExt|constructor#f; + constructor tearoff f = self2::BExt|constructor#_#f#tearOff; +} +static extension-type-member method BExt|constructor#(self2::C c) → self2::BExt% /* erasure=self2::C, declared=! */ + ; +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(self2::C c) → self2::BExt% /* erasure=self2::C, declared=! */ + return self2::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required self2::C c}) → self2::BExt% /* erasure=self2::C, declared=! */ + ; +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required self2::C c}) → self2::BExt% /* erasure=self2::C, declared=! */ + return self2::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.transformed.expect new file mode 100644 index 00000000000..9d2bbe42bcb --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.strong.transformed.expect @@ -0,0 +1,44 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::BExt% /* erasure=mai::C, declared=! */ bExt; + const constructor •({required mai::BExt% /* erasure=mai::C, declared=! */ bExt}) → self::A + : self::A::bExt = bExt, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(bExt: mai::BExt|constructor#f(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} +extension type BExt(mai::C c) { + abstract extension-type-member representation-field get c() → mai::C; + constructor • = mai::BExt|constructor#; + constructor tearoff • = mai::BExt|constructor#_#new#tearOff; + constructor f = mai::BExt|constructor#f; + constructor tearoff f = mai::BExt|constructor#_#f#tearOff; +} +static extension-type-member method BExt|constructor#(mai::C c) → mai::BExt% /* erasure=mai::C, declared=! */ { + lowered final mai::BExt% /* erasure=mai::C, declared=! */ #this = c; + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#new#tearOff(mai::C c) → mai::BExt% /* erasure=mai::C, declared=! */ + return mai::BExt|constructor#(c); +static extension-type-member method BExt|constructor#f({required mai::C c}) → mai::BExt% /* erasure=mai::C, declared=! */ { + lowered final mai::BExt% /* erasure=mai::C, declared=! */ #this; + #this = mai::BExt|constructor#(c); + return #this; +} +static extension-type-member synthetic method BExt|constructor#_#f#tearOff({required mai::C c}) → mai::BExt% /* erasure=mai::C, declared=! */ + return mai::BExt|constructor#f(c: c); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline.expect new file mode 100644 index 00000000000..bb99a2f8ae4 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +final a = A(bExt: .f(c: .f(0))); + +class A { + final BExt bExt; + const A({required this.bExt}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..ffee7ff4995 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main.dart.textual_outline_modelled.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +class A { + const A({required this.bExt}); + final BExt bExt; +} + +final a = A(bExt: .f(c: .f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main_lib.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main_lib.dart new file mode 100644 index 00000000000..72bb055e657 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_extension_type/main_lib.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2026, 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 C { + C.f(num n); +} + +extension type BExt(C c) { + BExt.f({required C c}) : this(c); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart new file mode 100644 index 00000000000..a4cbcfb5feb --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2026, 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. + +final a = A(b: .redirect(c: .f(0))); + +class A { + final B b; + const A({required this.b}); +} + +class B { + final C c; + const B({required this.c}); + + factory B.redirect({required C c}) = B; +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.expect new file mode 100644 index 00000000000..f1f08c4b60a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static factory redirect({required self::C c}) → self::B /* redirection-target: self::B::• */ + return new self::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new self::B::•(c: new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.modular.expect new file mode 100644 index 00000000000..f1f08c4b60a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.modular.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static factory redirect({required self::C c}) → self::B /* redirection-target: self::B::• */ + return new self::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new self::B::•(c: new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.outline.expect new file mode 100644 index 00000000000..6e23369ef49 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.outline.expect @@ -0,0 +1,23 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static factory redirect({required self::C c}) → self::B /* redirection-target: self::B::• */ + return new self::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → self::C + ; +} +static final field self::A a; diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.transformed.expect new file mode 100644 index 00000000000..f1f08c4b60a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.strong.transformed.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static factory redirect({required self::C c}) → self::B /* redirection-target: self::B::• */ + return new self::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new self::B::•(c: new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline.expect new file mode 100644 index 00000000000..63685d12fa1 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline.expect @@ -0,0 +1,16 @@ +final a = A(b: .redirect(c: .f(0))); + +class A { + final B b; + const A({required this.b}); +} + +class B { + final C c; + const B({required this.c}); + factory B.redirect({required C c}) = B; +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..f755ebf5ebf --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory.dart.textual_outline_modelled.expect @@ -0,0 +1,16 @@ +class A { + const A({required this.b}); + final B b; +} + +class B { + const B({required this.c}); + factory B.redirect({required C c}) = B; + final C c; +} + +class C { + C.f(num n); +} + +final a = A(b: .redirect(c: .f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart new file mode 100644 index 00000000000..d413b97a331 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2026, 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. + +import 'main_lib.dart'; + +final a = A(b: .redirect(c: .f(0))); + +class A { + final B b; + + const A({required this.b}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.expect new file mode 100644 index 00000000000..8ad01f8d9fe --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.expect @@ -0,0 +1,32 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new mai::B::•(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static factory redirect({required mai::C c}) → mai::B /* redirection-target: mai::B::• */ + return new mai::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.modular.expect new file mode 100644 index 00000000000..8ad01f8d9fe --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.modular.expect @@ -0,0 +1,32 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new mai::B::•(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static factory redirect({required mai::C c}) → mai::B /* redirection-target: mai::B::• */ + return new mai::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.outline.expect new file mode 100644 index 00000000000..17b3fc208ba --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.outline.expect @@ -0,0 +1,31 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a; + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static factory redirect({required mai::C c}) → mai::B /* redirection-target: mai::B::• */ + return new mai::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → mai::C + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.transformed.expect new file mode 100644 index 00000000000..8ad01f8d9fe --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.strong.transformed.expect @@ -0,0 +1,32 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: new mai::B::•(c: new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static factory redirect({required mai::C c}) → mai::B /* redirection-target: mai::B::• */ + return new mai::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline.expect new file mode 100644 index 00000000000..2a339618d84 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +final a = A(b: .redirect(c: .f(0))); + +class A { + final B b; + const A({required this.b}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..bf1584c0106 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main.dart.textual_outline_modelled.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +class A { + const A({required this.b}); + final B b; +} + +final a = A(b: .redirect(c: .f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main_lib.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main_lib.dart new file mode 100644 index 00000000000..5820a98fea3 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_redirecting_factory/main_lib.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2026, 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 B { + final C c; + const B({required this.c}); + + factory B.redirect({required C c}) = B; +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart new file mode 100644 index 00000000000..2bdf53e43dc --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2026, 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. + +final a = A(b: .f(.f(0))); + +class A { + final B b; + const A({required this.b}); +} + +class B { + final C c; + const B({required this.c}); + + static B f(C c) => B(c: c); +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.expect new file mode 100644 index 00000000000..b86370b6162 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static method f(self::C c) → self::B + return new self::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: self::B::f(new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.modular.expect new file mode 100644 index 00000000000..b86370b6162 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.modular.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static method f(self::C c) → self::B + return new self::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: self::B::f(new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.outline.expect new file mode 100644 index 00000000000..cf56c8bd204 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.outline.expect @@ -0,0 +1,23 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static method f(self::C c) → self::B + ; +} +class C extends core::Object { + constructor f(core::num n) → self::C + ; +} +static final field self::A a; diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.transformed.expect new file mode 100644 index 00000000000..b86370b6162 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.strong.transformed.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class A extends core::Object /*hasConstConstructor*/ { + final field self::B b; + const constructor •({required self::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +class B extends core::Object /*hasConstConstructor*/ { + final field self::C c; + const constructor •({required self::C c}) → self::B + : self::B::c = c, super core::Object::•() + ; + static method f(self::C c) → self::B + return new self::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → self::C + : super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: self::B::f(new self::C::f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline.expect new file mode 100644 index 00000000000..291a1ff3f6a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline.expect @@ -0,0 +1,16 @@ +final a = A(b: .f(.f(0))); + +class A { + final B b; + const A({required this.b}); +} + +class B { + final C c; + const B({required this.c}); + static B f(C c) => B(c: c); +} + +class C { + C.f(num n); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..b4ddf4fd378 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method.dart.textual_outline_modelled.expect @@ -0,0 +1,16 @@ +class A { + const A({required this.b}); + final B b; +} + +class B { + const B({required this.c}); + final C c; + static B f(C c) => B(c: c); +} + +class C { + C.f(num n); +} + +final a = A(b: .f(.f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart new file mode 100644 index 00000000000..51ad103bf8e --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2026, 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. + +import 'main_lib.dart'; + +final a = A(b: .f(.f(0))); + +class A { + final B b; + + const A({required this.b}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.expect new file mode 100644 index 00000000000..1fbfeaf2e65 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.expect @@ -0,0 +1,32 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: mai::B::f(new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static method f(mai::C c) → mai::B + return new mai::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.modular.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.modular.expect new file mode 100644 index 00000000000..1fbfeaf2e65 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.modular.expect @@ -0,0 +1,32 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: mai::B::f(new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static method f(mai::C c) → mai::B + return new mai::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.outline.expect new file mode 100644 index 00000000000..61edfe05b03 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.outline.expect @@ -0,0 +1,31 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a; + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static method f(mai::C c) → mai::B + ; +} +class C extends core::Object { + constructor f(core::num n) → mai::C + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.transformed.expect new file mode 100644 index 00000000000..1fbfeaf2e65 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.strong.transformed.expect @@ -0,0 +1,32 @@ +library; +import self as self; +import "dart:core" as core; +import "main_lib.dart" as mai; + +import "org-dartlang-testcase:///main_lib.dart"; + +class A extends core::Object /*hasConstConstructor*/ { + final field mai::B b; + const constructor •({required mai::B b}) → self::A + : self::A::b = b, super core::Object::•() + ; +} +static final field self::A a = new self::A::•(b: mai::B::f(new mai::C::f(0))); + +library; +import self as mai; +import "dart:core" as core; + +class B extends core::Object /*hasConstConstructor*/ { + final field mai::C c; + const constructor •({required mai::C c}) → mai::B + : mai::B::c = c, super core::Object::•() + ; + static method f(mai::C c) → mai::B + return new mai::B::•(c: c); +} +class C extends core::Object { + constructor f(core::num n) → mai::C + : super core::Object::•() + ; +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline.expect new file mode 100644 index 00000000000..75991beb2a7 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +final a = A(b: .f(.f(0))); + +class A { + final B b; + const A({required this.b}); +} diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..34b7ad28820 --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main.dart.textual_outline_modelled.expect @@ -0,0 +1,8 @@ +import 'main_lib.dart'; + +class A { + const A({required this.b}); + final B b; +} + +final a = A(b: .f(.f(0))); diff --git a/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main_lib.dart b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main_lib.dart new file mode 100644 index 00000000000..7b317aa975a --- /dev/null +++ b/pkg/front_end/testcases/dot_shorthands/nested_arguments_static_method/main_lib.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2026, 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 B { + final C c; + const B({required this.c}); + + static B f(C c) => B(c: c); +} + +class C { + C.f(num n); +}