From 0eb19fdba18b4e911f60a36b9534c3ace1a77eaf Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Mon, 1 Jun 2026 01:57:46 -0700 Subject: [PATCH] [cfe][PrimaryConstructors] Process parameter annotations This CL ensures the processing of parameter annotations on primary constructors. Since primary constructors with constructor body declarations are built in two parts, the constructor is not finished when the primary constructor is built, but instead delayed to when the primary constructor body declaration is built. This conditional code path accidentally left parameter annotations unprocessed. Fixes b/517220569 Change-Id: I8ec82283dc60a743c22cb03c041d2975e95941bc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/507980 Reviewed-by: Chloe Stefantsova Commit-Queue: Johnni Winther --- pkg/front_end/lib/src/kernel/resolver.dart | 3 +- .../parameter_annotation.dart | 13 +++++++ .../parameter_annotation.dart.strong.expect | 36 +++++++++++++++++++ ...eter_annotation.dart.strong.modular.expect | 36 +++++++++++++++++++ ...eter_annotation.dart.strong.outline.expect | 24 +++++++++++++ ..._annotation.dart.strong.transformed.expect | 36 +++++++++++++++++++ ...ter_annotation.dart.textual_outline.expect | 9 +++++ ...ation.dart.textual_outline_modelled.expect | 9 +++++ 8 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart create mode 100644 pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.expect create mode 100644 pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline_modelled.expect diff --git a/pkg/front_end/lib/src/kernel/resolver.dart b/pkg/front_end/lib/src/kernel/resolver.dart index 796bc3fb450..dc9b15904f8 100644 --- a/pkg/front_end/lib/src/kernel/resolver.dart +++ b/pkg/front_end/lib/src/kernel/resolver.dart @@ -721,9 +721,8 @@ class Resolver { internalThisVariable: internalThisVariable, forPrimaryConstructor: true, ); - - context.performBacklog(result.annotations); } + context.performBacklog(result.annotations); } // Coverage-ignore(suite): Not run. on DebugAbort { diff --git a/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart new file mode 100644 index 00000000000..213014243f6 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.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 const Self(); + +class Base { + Base(int x); +} + +class MyComponent(@Self() final int? x) extends Base { + this : super(42); +} diff --git a/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.expect b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.expect new file mode 100644 index 00000000000..2ede27c910e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class Self extends core::Object /*hasConstConstructor*/ { + const constructor •() → self::Self + : super core::Object::•() + ; + static synthetic method _#new#tearOff() → self::Self + return new self::Self::•(); +} +class Base extends core::Object { + constructor •(core::int x) → self::Base + : super core::Object::•() + ; + static synthetic method _#new#tearOff(core::int x) → self::Base + return new self::Base::•(x); +} +class MyComponent extends self::Base { + final field core::int? x; + constructor •(@#C1 final initializing-formal core::int? x) → self::MyComponent + : self::MyComponent::x = x, super self::Base::•(42) + ; + static synthetic method _#new#tearOff(core::int? x) → self::MyComponent + return new self::MyComponent::•(x); +} + +constants { + #C1 = self::Self {} +} + + +Constructor coverage from constants: +org-dartlang-testcase:///parameter_annotation.dart: +- Self. (from org-dartlang-testcase:///parameter_annotation.dart:5:17) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.modular.expect b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.modular.expect new file mode 100644 index 00000000000..2ede27c910e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.modular.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class Self extends core::Object /*hasConstConstructor*/ { + const constructor •() → self::Self + : super core::Object::•() + ; + static synthetic method _#new#tearOff() → self::Self + return new self::Self::•(); +} +class Base extends core::Object { + constructor •(core::int x) → self::Base + : super core::Object::•() + ; + static synthetic method _#new#tearOff(core::int x) → self::Base + return new self::Base::•(x); +} +class MyComponent extends self::Base { + final field core::int? x; + constructor •(@#C1 final initializing-formal core::int? x) → self::MyComponent + : self::MyComponent::x = x, super self::Base::•(42) + ; + static synthetic method _#new#tearOff(core::int? x) → self::MyComponent + return new self::MyComponent::•(x); +} + +constants { + #C1 = self::Self {} +} + + +Constructor coverage from constants: +org-dartlang-testcase:///parameter_annotation.dart: +- Self. (from org-dartlang-testcase:///parameter_annotation.dart:5:17) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.outline.expect b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.outline.expect new file mode 100644 index 00000000000..12c06f4f931 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.outline.expect @@ -0,0 +1,24 @@ +library; +import self as self; +import "dart:core" as core; + +class Self extends core::Object /*hasConstConstructor*/ { + const constructor •() → self::Self + : super core::Object::•() + ; + static synthetic method _#new#tearOff() → self::Self + return new self::Self::•(); +} +class Base extends core::Object { + constructor •(core::int x) → self::Base + ; + static synthetic method _#new#tearOff(core::int x) → self::Base + return new self::Base::•(x); +} +class MyComponent extends self::Base { + final field core::int? x; + constructor •(final initializing-formal core::int? x) → self::MyComponent + ; + static synthetic method _#new#tearOff(core::int? x) → self::MyComponent + return new self::MyComponent::•(x); +} diff --git a/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.transformed.expect new file mode 100644 index 00000000000..2ede27c910e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.strong.transformed.expect @@ -0,0 +1,36 @@ +library; +import self as self; +import "dart:core" as core; + +class Self extends core::Object /*hasConstConstructor*/ { + const constructor •() → self::Self + : super core::Object::•() + ; + static synthetic method _#new#tearOff() → self::Self + return new self::Self::•(); +} +class Base extends core::Object { + constructor •(core::int x) → self::Base + : super core::Object::•() + ; + static synthetic method _#new#tearOff(core::int x) → self::Base + return new self::Base::•(x); +} +class MyComponent extends self::Base { + final field core::int? x; + constructor •(@#C1 final initializing-formal core::int? x) → self::MyComponent + : self::MyComponent::x = x, super self::Base::•(42) + ; + static synthetic method _#new#tearOff(core::int? x) → self::MyComponent + return new self::MyComponent::•(x); +} + +constants { + #C1 = self::Self {} +} + + +Constructor coverage from constants: +org-dartlang-testcase:///parameter_annotation.dart: +- Self. (from org-dartlang-testcase:///parameter_annotation.dart:5:17) +- Object. (from org-dartlang-sdk:///lib/core/object.dart) diff --git a/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline.expect new file mode 100644 index 00000000000..46c6b312aab --- /dev/null +++ b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline.expect @@ -0,0 +1,9 @@ +class const Self(); + +class Base { + Base(int x); +} + +class MyComponent(@Self() final int? x) extends Base { + this : super(42); +} diff --git a/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..c73d56dbd87 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/primary_constructors/parameter_annotation.dart.textual_outline_modelled.expect @@ -0,0 +1,9 @@ +class Base { + Base(int x); +} + +class MyComponent(@Self() final int? x) extends Base { + this : super(42); +} + +class const Self();