From a00d45f46724c06edae99c6f9134971de891ba8d Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 14 Nov 2024 10:03:02 +0000 Subject: [PATCH] [CFE/kernel] Fix crash on TypeParameter.declaration when compiling constructor with annotation on type parameter with name clash Change-Id: Ic56cfc8f4eaafe3a6d25371b6ae5deb452651543 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395001 Commit-Queue: Jens Johansen Reviewed-by: Johnni Winther --- .../source/source_constructor_builder.dart | 3 +++ .../src/source/source_function_builder.dart | 6 ++++- ...e_parameter_name_clash_on_constructor.dart | 9 +++++++ ...me_clash_on_constructor.dart.strong.expect | 25 +++++++++++++++++++ ..._on_constructor.dart.strong.modular.expect | 25 +++++++++++++++++++ ..._on_constructor.dart.strong.outline.expect | 21 ++++++++++++++++ ...constructor.dart.strong.transformed.expect | 25 +++++++++++++++++++ ...on_constructor.dart.textual_outline.expect | 5 ++++ .../testcases/textual_outline.status | 1 + 9 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart create mode 100644 pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.expect create mode 100644 pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.modular.expect create mode 100644 pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.outline.expect create mode 100644 pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.textual_outline.expect diff --git a/pkg/front_end/lib/src/source/source_constructor_builder.dart b/pkg/front_end/lib/src/source/source_constructor_builder.dart index aae958567f0d..7a0efd0b1589 100644 --- a/pkg/front_end/lib/src/source/source_constructor_builder.dart +++ b/pkg/front_end/lib/src/source/source_constructor_builder.dart @@ -465,6 +465,9 @@ class DeclaredSourceConstructorBuilder @override Builder get parent => declarationBuilder; + @override + bool get supportsTypeParameters => false; + @override // Coverage-ignore(suite): Not run. Name get memberName => _memberName.name; diff --git a/pkg/front_end/lib/src/source/source_function_builder.dart b/pkg/front_end/lib/src/source/source_function_builder.dart index 1ac8f69cd2e1..8ce0e1592dc9 100644 --- a/pkg/front_end/lib/src/source/source_function_builder.dart +++ b/pkg/front_end/lib/src/source/source_function_builder.dart @@ -312,6 +312,8 @@ abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl @override bool get isNative => nativeMethodName != null; + bool get supportsTypeParameters => true; + void buildFunction() { function.asyncMarker = asyncModifier; function.body = body; @@ -330,7 +332,9 @@ abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl if (typeParameters != null) { for (NominalParameterBuilder t in typeParameters!) { TypeParameter parameter = t.parameter; - function.typeParameters.add(parameter); + if (supportsTypeParameters) { + function.typeParameters.add(parameter); + } if (needsCheckVisitor != null) { if (parameter.bound.accept(needsCheckVisitor)) { parameter.isCovariantByClass = true; diff --git a/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart new file mode 100644 index 000000000000..8ad1ed666b43 --- /dev/null +++ b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2024, 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. + +const int x = 42; + +class Foo { + Foo<@x x>() {} +} diff --git a/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.expect b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.expect new file mode 100644 index 000000000000..b4480ac8f0db --- /dev/null +++ b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.expect @@ -0,0 +1,25 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:6: Error: Constructors can't have type parameters. +// Try removing the type parameters. +// Foo<@x x>() {} +// ^^^^^^ +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:8: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor. +// Foo<@x x>() {} +// ^ +// +import self as self; +import "dart:core" as core; + +class Foo extends core::Object { + constructor •() → self::Foo + : super core::Object::•() {} +} +static const field core::int x = #C1; + +constants { + #C1 = 42 +} diff --git a/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.modular.expect b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.modular.expect new file mode 100644 index 000000000000..b4480ac8f0db --- /dev/null +++ b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.modular.expect @@ -0,0 +1,25 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:6: Error: Constructors can't have type parameters. +// Try removing the type parameters. +// Foo<@x x>() {} +// ^^^^^^ +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:8: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor. +// Foo<@x x>() {} +// ^ +// +import self as self; +import "dart:core" as core; + +class Foo extends core::Object { + constructor •() → self::Foo + : super core::Object::•() {} +} +static const field core::int x = #C1; + +constants { + #C1 = 42 +} diff --git a/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.outline.expect b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.outline.expect new file mode 100644 index 000000000000..9e785316ca4c --- /dev/null +++ b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.outline.expect @@ -0,0 +1,21 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:6: Error: Constructors can't have type parameters. +// Try removing the type parameters. +// Foo<@x x>() {} +// ^^^^^^ +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:8: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor. +// Foo<@x x>() {} +// ^ +// +import self as self; +import "dart:core" as core; + +class Foo extends core::Object { + constructor •() → self::Foo + ; +} +static const field core::int x = 42; diff --git a/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.transformed.expect new file mode 100644 index 000000000000..b4480ac8f0db --- /dev/null +++ b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.strong.transformed.expect @@ -0,0 +1,25 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:6: Error: Constructors can't have type parameters. +// Try removing the type parameters. +// Foo<@x x>() {} +// ^^^^^^ +// +// pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart:8:8: Error: This can't be used as an annotation; an annotation should be a reference to a compile-time constant variable, or a call to a constant constructor. +// Foo<@x x>() {} +// ^ +// +import self as self; +import "dart:core" as core; + +class Foo extends core::Object { + constructor •() → self::Foo + : super core::Object::•() {} +} +static const field core::int x = #C1; + +constants { + #C1 = 42 +} diff --git a/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.textual_outline.expect new file mode 100644 index 000000000000..7c6b6ae5c337 --- /dev/null +++ b/pkg/front_end/testcases/regress/annotation_on_type_parameter_name_clash_on_constructor.dart.textual_outline.expect @@ -0,0 +1,5 @@ +const int x = 42; + +class Foo { + Foo<@x x>() {} +} diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status index b9bf65dbe5a0..b668ef706328 100644 --- a/pkg/front_end/testcases/textual_outline.status +++ b/pkg/front_end/testcases/textual_outline.status @@ -7,6 +7,7 @@ # These tests have errors in them which isn't reported by the parser but the # formatter still sees as syntax errors and thus won't format. +regress/annotation_on_type_parameter_name_clash_on_constructor: FormatterCrash extension_types/const_constructor_body: FormatterCrash extension_types/field_access: FormatterCrash extension_types/issue52119: FormatterCrash