Skip to content

Commit 9e36a86

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Report errors on super formal parameters in extension types
Closes #53212 Part of #49731 Change-Id: I4f209ab220bb0a47328a60d91e66a891d8fc1362 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331048 Commit-Queue: Chloe Stefantsova <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 4c59616 commit 9e36a86

12 files changed

+535
-1
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

+13
Original file line numberDiff line numberDiff line change
@@ -4398,6 +4398,19 @@ Message _withArgumentsExtensionTypeCombinedMemberSignatureFailed(
43984398
arguments: {'name': name, 'name2': name2});
43994399
}
44004400

4401+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4402+
const Code<Null> codeExtensionTypeConstructorWithSuperFormalParameter =
4403+
messageExtensionTypeConstructorWithSuperFormalParameter;
4404+
4405+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4406+
const MessageCode messageExtensionTypeConstructorWithSuperFormalParameter =
4407+
const MessageCode("ExtensionTypeConstructorWithSuperFormalParameter",
4408+
analyzerCodes: <String>[
4409+
"EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_FORMAL_PARAMETER"
4410+
],
4411+
problemMessage:
4412+
r"""Extension type constructors can't declare super formal parameters.""");
4413+
44014414
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
44024415
const Code<Null> codeExtensionTypeDeclarationCause =
44034416
messageExtensionTypeDeclarationCause;

pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart

+18-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import '../messages.dart'
3535
show
3636
LocatedMessage,
3737
Message,
38+
messageExtensionTypeConstructorWithSuperFormalParameter,
3839
messageMoreThanOneSuperInitializer,
3940
messageRedirectingConstructorWithAnotherInitializer,
4041
messageRedirectingConstructorWithMultipleRedirectInitializers,
@@ -1157,7 +1158,23 @@ class SourceExtensionTypeConstructorBuilder
11571158
List<DelayedDefaultValueCloner> delayedDefaultValueCloners) {}
11581159

11591160
@override
1160-
void _inferSuperInitializingFormals(ClassHierarchyBase hierarchy) {}
1161+
void _inferSuperInitializingFormals(ClassHierarchyBase hierarchy) {
1162+
if (formals != null) {
1163+
for (FormalParameterBuilder formal in formals!) {
1164+
if (formal.isSuperInitializingFormal) {
1165+
TypeBuilder formalTypeBuilder = formal.type;
1166+
if (formalTypeBuilder is InferableTypeBuilder) {
1167+
libraryBuilder.addProblem(
1168+
messageExtensionTypeConstructorWithSuperFormalParameter,
1169+
formal.charOffset,
1170+
formal.name.length,
1171+
formal.fileUri);
1172+
formalTypeBuilder.registerType(const InvalidType());
1173+
}
1174+
}
1175+
}
1176+
}
1177+
}
11611178

11621179
@override
11631180
int buildBodyNodes(BuildNodesCallback f) {

pkg/front_end/messages.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -7433,3 +7433,10 @@ MultipleRepresentationFields:
74337433
script: |
74347434
extension type E(int foo, String bar) {}
74357435
analyzerCode: MULTIPLE_REPRESENTATION_FIELDS
7436+
7437+
ExtensionTypeConstructorWithSuperFormalParameter:
7438+
problemMessage: "Extension type constructors can't declare super formal parameters."
7439+
experiments: inline-class
7440+
script: |
7441+
extension type A(int foo) { A.named(this.foo, super.bar); }
7442+
analyzerCode: EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_FORMAL_PARAMETER
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by b
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
extension type E1(int foo) {
6+
E1.named(this.foo, super.bar); // Error.
7+
}
8+
9+
extension type E2(int foo) {
10+
E2.named(this.foo, {required super.bar}); // Error.
11+
}
12+
13+
extension type E3(int foo) {
14+
E3.named(this.foo, [super.bar = null]);
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue53212.dart:6:28: Error: Extension type constructors can't declare super formal parameters.
6+
// E1.named(this.foo, super.bar); // Error.
7+
// ^^^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue53212.dart:10:38: Error: Extension type constructors can't declare super formal parameters.
10+
// E2.named(this.foo, {required super.bar}); // Error.
11+
// ^^^
12+
//
13+
// pkg/front_end/testcases/extension_types/issue53212.dart:14:29: Error: Extension type constructors can't declare super formal parameters.
14+
// E3.named(this.foo, [super.bar = null]);
15+
// ^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
extension type E1(core::int foo) {
21+
abstract inline-class-member representation-field get foo() → core::int;
22+
constructor • = self::E1|constructor#;
23+
constructor tearoff • = self::E1|constructor#_#new#tearOff;
24+
constructor named = self::E1|constructor#named;
25+
constructor tearoff named = self::E1|constructor#_#named#tearOff;
26+
}
27+
extension type E2(core::int foo) {
28+
abstract inline-class-member representation-field get foo() → core::int;
29+
constructor • = self::E2|constructor#;
30+
constructor tearoff • = self::E2|constructor#_#new#tearOff;
31+
constructor named = self::E2|constructor#named;
32+
constructor tearoff named = self::E2|constructor#_#named#tearOff;
33+
}
34+
extension type E3(core::int foo) {
35+
abstract inline-class-member representation-field get foo() → core::int;
36+
constructor • = self::E3|constructor#;
37+
constructor tearoff • = self::E3|constructor#_#new#tearOff;
38+
constructor named = self::E3|constructor#named;
39+
constructor tearoff named = self::E3|constructor#_#named#tearOff;
40+
}
41+
static inline-class-member method E1|constructor#(core::int foo) → self::E1 /* = core::int */ {
42+
lowered final self::E1 /* = core::int */ #this = foo;
43+
return #this;
44+
}
45+
static inline-class-member method E1|constructor#_#new#tearOff(core::int foo) → self::E1 /* = core::int */
46+
return self::E1|constructor#(foo);
47+
static inline-class-member method E1|constructor#named(core::int foo, invalid-type bar) → self::E1 /* = core::int */ {
48+
lowered final self::E1 /* = core::int */ #this = foo;
49+
return #this;
50+
}
51+
static inline-class-member method E1|constructor#_#named#tearOff(core::int foo, invalid-type bar) → self::E1 /* = core::int */
52+
return self::E1|constructor#named(foo, bar);
53+
static inline-class-member method E2|constructor#(core::int foo) → self::E2 /* = core::int */ {
54+
lowered final self::E2 /* = core::int */ #this = foo;
55+
return #this;
56+
}
57+
static inline-class-member method E2|constructor#_#new#tearOff(core::int foo) → self::E2 /* = core::int */
58+
return self::E2|constructor#(foo);
59+
static inline-class-member method E2|constructor#named(core::int foo, {required invalid-type bar = #C1}) → self::E2 /* = core::int */ {
60+
lowered final self::E2 /* = core::int */ #this = foo;
61+
return #this;
62+
}
63+
static inline-class-member method E2|constructor#_#named#tearOff(core::int foo, {required invalid-type bar}) → self::E2 /* = core::int */
64+
return self::E2|constructor#named(foo, bar: bar);
65+
static inline-class-member method E3|constructor#(core::int foo) → self::E3 /* = core::int */ {
66+
lowered final self::E3 /* = core::int */ #this = foo;
67+
return #this;
68+
}
69+
static inline-class-member method E3|constructor#_#new#tearOff(core::int foo) → self::E3 /* = core::int */
70+
return self::E3|constructor#(foo);
71+
static inline-class-member method E3|constructor#named(core::int foo, [has-declared-initializer invalid-type bar = #C1]) → self::E3 /* = core::int */ {
72+
lowered final self::E3 /* = core::int */ #this = foo;
73+
return #this;
74+
}
75+
static inline-class-member method E3|constructor#_#named#tearOff(core::int foo, [has-declared-initializer invalid-type bar]) → self::E3 /* = core::int */
76+
return self::E3|constructor#named(foo, bar);
77+
78+
constants {
79+
#C1 = null
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue53212.dart:6:28: Error: Extension type constructors can't declare super formal parameters.
6+
// E1.named(this.foo, super.bar); // Error.
7+
// ^^^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue53212.dart:10:38: Error: Extension type constructors can't declare super formal parameters.
10+
// E2.named(this.foo, {required super.bar}); // Error.
11+
// ^^^
12+
//
13+
// pkg/front_end/testcases/extension_types/issue53212.dart:14:29: Error: Extension type constructors can't declare super formal parameters.
14+
// E3.named(this.foo, [super.bar = null]);
15+
// ^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
extension type E1(core::int foo) {
21+
abstract inline-class-member representation-field get foo() → core::int;
22+
constructor • = self::E1|constructor#;
23+
constructor tearoff • = self::E1|constructor#_#new#tearOff;
24+
constructor named = self::E1|constructor#named;
25+
constructor tearoff named = self::E1|constructor#_#named#tearOff;
26+
}
27+
extension type E2(core::int foo) {
28+
abstract inline-class-member representation-field get foo() → core::int;
29+
constructor • = self::E2|constructor#;
30+
constructor tearoff • = self::E2|constructor#_#new#tearOff;
31+
constructor named = self::E2|constructor#named;
32+
constructor tearoff named = self::E2|constructor#_#named#tearOff;
33+
}
34+
extension type E3(core::int foo) {
35+
abstract inline-class-member representation-field get foo() → core::int;
36+
constructor • = self::E3|constructor#;
37+
constructor tearoff • = self::E3|constructor#_#new#tearOff;
38+
constructor named = self::E3|constructor#named;
39+
constructor tearoff named = self::E3|constructor#_#named#tearOff;
40+
}
41+
static inline-class-member method E1|constructor#(core::int foo) → self::E1 /* = core::int */ {
42+
lowered final self::E1 /* = core::int */ #this = foo;
43+
return #this;
44+
}
45+
static inline-class-member method E1|constructor#_#new#tearOff(core::int foo) → self::E1 /* = core::int */
46+
return self::E1|constructor#(foo);
47+
static inline-class-member method E1|constructor#named(core::int foo, invalid-type bar) → self::E1 /* = core::int */ {
48+
lowered final self::E1 /* = core::int */ #this = foo;
49+
return #this;
50+
}
51+
static inline-class-member method E1|constructor#_#named#tearOff(core::int foo, invalid-type bar) → self::E1 /* = core::int */
52+
return self::E1|constructor#named(foo, bar);
53+
static inline-class-member method E2|constructor#(core::int foo) → self::E2 /* = core::int */ {
54+
lowered final self::E2 /* = core::int */ #this = foo;
55+
return #this;
56+
}
57+
static inline-class-member method E2|constructor#_#new#tearOff(core::int foo) → self::E2 /* = core::int */
58+
return self::E2|constructor#(foo);
59+
static inline-class-member method E2|constructor#named(core::int foo, {required invalid-type bar = #C1}) → self::E2 /* = core::int */ {
60+
lowered final self::E2 /* = core::int */ #this = foo;
61+
return #this;
62+
}
63+
static inline-class-member method E2|constructor#_#named#tearOff(core::int foo, {required invalid-type bar}) → self::E2 /* = core::int */
64+
return self::E2|constructor#named(foo, bar: bar);
65+
static inline-class-member method E3|constructor#(core::int foo) → self::E3 /* = core::int */ {
66+
lowered final self::E3 /* = core::int */ #this = foo;
67+
return #this;
68+
}
69+
static inline-class-member method E3|constructor#_#new#tearOff(core::int foo) → self::E3 /* = core::int */
70+
return self::E3|constructor#(foo);
71+
static inline-class-member method E3|constructor#named(core::int foo, [has-declared-initializer invalid-type bar = #C1]) → self::E3 /* = core::int */ {
72+
lowered final self::E3 /* = core::int */ #this = foo;
73+
return #this;
74+
}
75+
static inline-class-member method E3|constructor#_#named#tearOff(core::int foo, [has-declared-initializer invalid-type bar]) → self::E3 /* = core::int */
76+
return self::E3|constructor#named(foo, bar);
77+
78+
constants {
79+
#C1 = null
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extension type E1(int foo) {
2+
E1.named(this.foo, super.bar);
3+
}
4+
extension type E2(int foo) {
5+
E2.named(this.foo, {required super.bar});
6+
}
7+
extension type E3(int foo) {
8+
E3.named(this.foo, [super.bar = null]);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extension type E1(int foo) {
2+
E1.named(this.foo, super.bar);
3+
}
4+
extension type E2(int foo) {
5+
E2.named(this.foo, {required super.bar});
6+
}
7+
extension type E3(int foo) {
8+
E3.named(this.foo, [super.bar = null]);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue53212.dart:6:28: Error: Extension type constructors can't declare super formal parameters.
6+
// E1.named(this.foo, super.bar); // Error.
7+
// ^^^
8+
//
9+
// pkg/front_end/testcases/extension_types/issue53212.dart:10:38: Error: Extension type constructors can't declare super formal parameters.
10+
// E2.named(this.foo, {required super.bar}); // Error.
11+
// ^^^
12+
//
13+
// pkg/front_end/testcases/extension_types/issue53212.dart:14:29: Error: Extension type constructors can't declare super formal parameters.
14+
// E3.named(this.foo, [super.bar = null]);
15+
// ^^^
16+
//
17+
import self as self;
18+
import "dart:core" as core;
19+
20+
extension type E1(core::int foo) {
21+
abstract inline-class-member representation-field get foo() → core::int;
22+
constructor • = self::E1|constructor#;
23+
constructor tearoff • = self::E1|constructor#_#new#tearOff;
24+
constructor named = self::E1|constructor#named;
25+
constructor tearoff named = self::E1|constructor#_#named#tearOff;
26+
}
27+
extension type E2(core::int foo) {
28+
abstract inline-class-member representation-field get foo() → core::int;
29+
constructor • = self::E2|constructor#;
30+
constructor tearoff • = self::E2|constructor#_#new#tearOff;
31+
constructor named = self::E2|constructor#named;
32+
constructor tearoff named = self::E2|constructor#_#named#tearOff;
33+
}
34+
extension type E3(core::int foo) {
35+
abstract inline-class-member representation-field get foo() → core::int;
36+
constructor • = self::E3|constructor#;
37+
constructor tearoff • = self::E3|constructor#_#new#tearOff;
38+
constructor named = self::E3|constructor#named;
39+
constructor tearoff named = self::E3|constructor#_#named#tearOff;
40+
}
41+
static inline-class-member method E1|constructor#(core::int foo) → self::E1 /* = core::int */ {
42+
lowered final self::E1 /* = core::int */ #this = foo;
43+
return #this;
44+
}
45+
static inline-class-member method E1|constructor#_#new#tearOff(core::int foo) → self::E1 /* = core::int */
46+
return self::E1|constructor#(foo);
47+
static inline-class-member method E1|constructor#named(core::int foo, invalid-type bar) → self::E1 /* = core::int */ {
48+
lowered final self::E1 /* = core::int */ #this = foo;
49+
return #this;
50+
}
51+
static inline-class-member method E1|constructor#_#named#tearOff(core::int foo, invalid-type bar) → self::E1 /* = core::int */
52+
return self::E1|constructor#named(foo, bar);
53+
static inline-class-member method E2|constructor#(core::int foo) → self::E2 /* = core::int */ {
54+
lowered final self::E2 /* = core::int */ #this = foo;
55+
return #this;
56+
}
57+
static inline-class-member method E2|constructor#_#new#tearOff(core::int foo) → self::E2 /* = core::int */
58+
return self::E2|constructor#(foo);
59+
static inline-class-member method E2|constructor#named(core::int foo, {required invalid-type bar = #C1}) → self::E2 /* = core::int */ {
60+
lowered final self::E2 /* = core::int */ #this = foo;
61+
return #this;
62+
}
63+
static inline-class-member method E2|constructor#_#named#tearOff(core::int foo, {required invalid-type bar}) → self::E2 /* = core::int */
64+
return self::E2|constructor#named(foo, bar: bar);
65+
static inline-class-member method E3|constructor#(core::int foo) → self::E3 /* = core::int */ {
66+
lowered final self::E3 /* = core::int */ #this = foo;
67+
return #this;
68+
}
69+
static inline-class-member method E3|constructor#_#new#tearOff(core::int foo) → self::E3 /* = core::int */
70+
return self::E3|constructor#(foo);
71+
static inline-class-member method E3|constructor#named(core::int foo, [has-declared-initializer invalid-type bar = #C1]) → self::E3 /* = core::int */ {
72+
lowered final self::E3 /* = core::int */ #this = foo;
73+
return #this;
74+
}
75+
static inline-class-member method E3|constructor#_#named#tearOff(core::int foo, [has-declared-initializer invalid-type bar]) → self::E3 /* = core::int */
76+
return self::E3|constructor#named(foo, bar);
77+
78+
constants {
79+
#C1 = null
80+
}

0 commit comments

Comments
 (0)