Skip to content

Commit d003570

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Include dill in propagating errors in redirecting factories
Redirecting factory chains may include a mix of source- and dill- factory builders. The error propagation should work in that case too. This is a follow-up to https://dart-review.googlesource.com/c/sdk/+/332403/comment/14b70a92_c6e1a91e/ Part of #49731 Change-Id: I74be2a47260c2c24c2fc871b7f1521546f056a03 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/333162 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent 28a4b55 commit d003570

35 files changed

+1576
-2
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import '../builder/function_builder.dart';
1515
import '../builder/metadata_builder.dart';
1616
import '../builder/type_builder.dart';
1717
import '../dill/dill_member_builder.dart';
18+
import '../dill/dill_extension_type_member_builder.dart';
1819
import '../fasta_codes.dart';
1920
import '../identifiers.dart';
2021
import '../kernel/body_builder_context.dart';
@@ -610,14 +611,16 @@ class RedirectingFactoryBuilder extends SourceFactoryBuilder {
610611
if (targetBuilder == null) return null;
611612
if (targetBuilder is FunctionBuilder) {
612613
targetNode = targetBuilder.function;
614+
} else if (targetBuilder is DillExtensionTypeFactoryBuilder) {
615+
targetNode = targetBuilder.member.function!;
613616
} else if (targetBuilder is AmbiguousBuilder) {
614617
// Multiple definitions with the same name: An error has already been
615618
// issued.
616619
// TODO(http://dartbug.com/35294): Unfortunate error; see also
617620
// https://dart-review.googlesource.com/c/sdk/+/85390/.
618621
return null;
619622
} else {
620-
unhandled("${redirectionTarget.target}", "computeRedirecteeType",
623+
unhandled("${targetBuilder.runtimeType}", "computeRedirecteeType",
621624
charOffset, fileUri);
622625
}
623626

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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 a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
class A1 {
6+
final int foo;
7+
const A1(this.foo);
8+
const factory A1.redir(A1 it) = E1.redir;
9+
}
10+
11+
extension type const E1(A1 it) implements A1 {
12+
const factory E1.redir(A1 it) = E1;
13+
}
14+
15+
test1() {
16+
const A1 a1 = const A1(0);
17+
expectIdentical(const A1.redir(a1), a1);
18+
}
19+
20+
class A2 {
21+
final int foo;
22+
const A2(this.foo);
23+
const factory A2.redir(bool b) = E2.pick;
24+
}
25+
26+
class B2 extends A2 {
27+
static const B2 element = const B2(0);
28+
const B2(super.foo);
29+
}
30+
31+
class C2 extends A2 {
32+
static const C2 element = const C2(0);
33+
const C2(super.foo);
34+
}
35+
36+
extension type const E2(A2 it) implements A2 {
37+
const E2.pick(bool b) : this(b ? B2.element : C2.element);
38+
}
39+
40+
test2() {
41+
expectIdentical(const A2.redir(true), B2.element);
42+
expectIdentical(const A2.redir(false), C2.element);
43+
}
44+
45+
expectIdentical(expected, actual) {
46+
if (!identical(expected, actual)) {
47+
throw "Expected '${expected}', actual '${actual}'.";
48+
}
49+
}
50+
51+
main() {
52+
test1();
53+
test2();
54+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class A1 extends core::Object /*hasConstConstructor*/ {
6+
final field core::int foo;
7+
const constructor •(core::int foo) → self::A1
8+
: self::A1::foo = foo, super core::Object::•()
9+
;
10+
static factory redir(self::A1 it) → self::A1 /* redirection-target: self::E1|constructor#redir */
11+
return self::E1|constructor#redir(it);
12+
}
13+
class A2 extends core::Object /*hasConstConstructor*/ {
14+
final field core::int foo;
15+
const constructor •(core::int foo) → self::A2
16+
: self::A2::foo = foo, super core::Object::•()
17+
;
18+
static factory redir(core::bool b) → self::A2 /* redirection-target: self::E2|constructor#pick */
19+
return self::E2|constructor#pick(b);
20+
}
21+
class B2 extends self::A2 /*hasConstConstructor*/ {
22+
static const field self::B2 element = #C2;
23+
const constructor •(core::int foo) → self::B2
24+
: super self::A2::•(foo)
25+
;
26+
}
27+
class C2 extends self::A2 /*hasConstConstructor*/ {
28+
static const field self::C2 element = #C3;
29+
const constructor •(core::int foo) → self::C2
30+
: super self::A2::•(foo)
31+
;
32+
}
33+
extension type E1(self::A1 it) implements self::A1 {
34+
abstract inline-class-member representation-field get it() → self::A1;
35+
constructor • = self::E1|constructor#;
36+
constructor tearoff • = self::E1|constructor#_#new#tearOff;
37+
static redirecting-factory redir = self::E1|constructor#redir;
38+
static redirecting-factory tearoff redir = self::E1|constructor#_#redir#tearOff;
39+
}
40+
extension type E2(self::A2 it) implements self::A2 {
41+
abstract inline-class-member representation-field get it() → self::A2;
42+
constructor • = self::E2|constructor#;
43+
constructor tearoff • = self::E2|constructor#_#new#tearOff;
44+
constructor pick = self::E2|constructor#pick;
45+
constructor tearoff pick = self::E2|constructor#_#pick#tearOff;
46+
}
47+
static inline-class-member method E1|constructor#(self::A1 it) → self::E1 /* = self::A1 */ {
48+
lowered final self::E1 /* = self::A1 */ #this = it;
49+
return #this;
50+
}
51+
static inline-class-member method E1|constructor#_#new#tearOff(self::A1 it) → self::E1 /* = self::A1 */
52+
return self::E1|constructor#(it);
53+
static inline-class-member method E1|constructor#redir(self::A1 it) → self::E1 /* = self::A1 */ /* redirection-target: self::E1|constructor# */
54+
return self::E1|constructor#(it);
55+
static inline-class-member method E1|constructor#_#redir#tearOff(self::A1 it) → self::E1 /* = self::A1 */
56+
return self::E1|constructor#(it);
57+
static method test1() → dynamic {
58+
self::expectIdentical(#C4, #C4);
59+
}
60+
static inline-class-member method E2|constructor#(self::A2 it) → self::E2 /* = self::A2 */ {
61+
lowered final self::E2 /* = self::A2 */ #this = it;
62+
return #this;
63+
}
64+
static inline-class-member method E2|constructor#_#new#tearOff(self::A2 it) → self::E2 /* = self::A2 */
65+
return self::E2|constructor#(it);
66+
static inline-class-member method E2|constructor#pick(core::bool b) → self::E2 /* = self::A2 */ {
67+
lowered final self::E2 /* = self::A2 */ #this;
68+
#this = self::E2|constructor#(b ?{self::A2} #C2 : #C3);
69+
return #this;
70+
}
71+
static inline-class-member method E2|constructor#_#pick#tearOff(core::bool b) → self::E2 /* = self::A2 */
72+
return self::E2|constructor#pick(b);
73+
static method test2() → dynamic {
74+
self::expectIdentical(#C2, #C2);
75+
self::expectIdentical(#C3, #C3);
76+
}
77+
static method expectIdentical(dynamic expected, dynamic actual) → dynamic {
78+
if(!core::identical(expected, actual)) {
79+
throw "Expected '${expected}', actual '${actual}'.";
80+
}
81+
}
82+
static method main() → dynamic {
83+
self::test1();
84+
self::test2();
85+
}
86+
87+
constants {
88+
#C1 = 0
89+
#C2 = self::B2 {foo:#C1}
90+
#C3 = self::C2 {foo:#C1}
91+
#C4 = self::A1 {foo:#C1}
92+
}
93+
94+
95+
Constructor coverage from constants:
96+
org-dartlang-testcase:///redirecting_factory_from_class.dart:
97+
- B2. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:28:9)
98+
- A2. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:22:9)
99+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
100+
- C2. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:33:9)
101+
- A1. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:7:9)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class A1 extends core::Object /*hasConstConstructor*/ {
6+
final field core::int foo;
7+
const constructor •(core::int foo) → self::A1
8+
: self::A1::foo = foo, super core::Object::•()
9+
;
10+
static factory redir(self::A1 it) → self::A1 /* redirection-target: self::E1|constructor#redir */
11+
return self::E1|constructor#redir(it);
12+
}
13+
class A2 extends core::Object /*hasConstConstructor*/ {
14+
final field core::int foo;
15+
const constructor •(core::int foo) → self::A2
16+
: self::A2::foo = foo, super core::Object::•()
17+
;
18+
static factory redir(core::bool b) → self::A2 /* redirection-target: self::E2|constructor#pick */
19+
return self::E2|constructor#pick(b);
20+
}
21+
class B2 extends self::A2 /*hasConstConstructor*/ {
22+
static const field self::B2 element = #C2;
23+
const constructor •(core::int foo) → self::B2
24+
: super self::A2::•(foo)
25+
;
26+
}
27+
class C2 extends self::A2 /*hasConstConstructor*/ {
28+
static const field self::C2 element = #C3;
29+
const constructor •(core::int foo) → self::C2
30+
: super self::A2::•(foo)
31+
;
32+
}
33+
extension type E1(self::A1 it) implements self::A1 {
34+
abstract inline-class-member representation-field get it() → self::A1;
35+
constructor • = self::E1|constructor#;
36+
constructor tearoff • = self::E1|constructor#_#new#tearOff;
37+
static redirecting-factory redir = self::E1|constructor#redir;
38+
static redirecting-factory tearoff redir = self::E1|constructor#_#redir#tearOff;
39+
}
40+
extension type E2(self::A2 it) implements self::A2 {
41+
abstract inline-class-member representation-field get it() → self::A2;
42+
constructor • = self::E2|constructor#;
43+
constructor tearoff • = self::E2|constructor#_#new#tearOff;
44+
constructor pick = self::E2|constructor#pick;
45+
constructor tearoff pick = self::E2|constructor#_#pick#tearOff;
46+
}
47+
static inline-class-member method E1|constructor#(self::A1 it) → self::E1 /* = self::A1 */ {
48+
lowered final self::E1 /* = self::A1 */ #this = it;
49+
return #this;
50+
}
51+
static inline-class-member method E1|constructor#_#new#tearOff(self::A1 it) → self::E1 /* = self::A1 */
52+
return self::E1|constructor#(it);
53+
static inline-class-member method E1|constructor#redir(self::A1 it) → self::E1 /* = self::A1 */ /* redirection-target: self::E1|constructor# */
54+
return self::E1|constructor#(it);
55+
static inline-class-member method E1|constructor#_#redir#tearOff(self::A1 it) → self::E1 /* = self::A1 */
56+
return self::E1|constructor#(it);
57+
static method test1() → dynamic {
58+
self::expectIdentical(#C4, #C4);
59+
}
60+
static inline-class-member method E2|constructor#(self::A2 it) → self::E2 /* = self::A2 */ {
61+
lowered final self::E2 /* = self::A2 */ #this = it;
62+
return #this;
63+
}
64+
static inline-class-member method E2|constructor#_#new#tearOff(self::A2 it) → self::E2 /* = self::A2 */
65+
return self::E2|constructor#(it);
66+
static inline-class-member method E2|constructor#pick(core::bool b) → self::E2 /* = self::A2 */ {
67+
lowered final self::E2 /* = self::A2 */ #this;
68+
#this = self::E2|constructor#(b ?{self::A2} #C2 : #C3);
69+
return #this;
70+
}
71+
static inline-class-member method E2|constructor#_#pick#tearOff(core::bool b) → self::E2 /* = self::A2 */
72+
return self::E2|constructor#pick(b);
73+
static method test2() → dynamic {
74+
self::expectIdentical(#C2, #C2);
75+
self::expectIdentical(#C3, #C3);
76+
}
77+
static method expectIdentical(dynamic expected, dynamic actual) → dynamic {
78+
if(!core::identical(expected, actual)) {
79+
throw "Expected '${expected}', actual '${actual}'.";
80+
}
81+
}
82+
static method main() → dynamic {
83+
self::test1();
84+
self::test2();
85+
}
86+
87+
constants {
88+
#C1 = 0
89+
#C2 = self::B2 {foo:#C1}
90+
#C3 = self::C2 {foo:#C1}
91+
#C4 = self::A1 {foo:#C1}
92+
}
93+
94+
95+
Constructor coverage from constants:
96+
org-dartlang-testcase:///redirecting_factory_from_class.dart:
97+
- B2. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:28:9)
98+
- A2. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:22:9)
99+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
100+
- C2. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:33:9)
101+
- A1. (from org-dartlang-testcase:///redirecting_factory_from_class.dart:7:9)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class A1 {
2+
final int foo;
3+
const A1(this.foo);
4+
const factory A1.redir(A1 it) = E1.redir;
5+
}
6+
extension type const E1(A1 it) implements A1 {
7+
const factory E1.redir(A1 it) = E1;
8+
}
9+
test1() {}
10+
class A2 {
11+
final int foo;
12+
const A2(this.foo);
13+
const factory A2.redir(bool b) = E2.pick;
14+
}
15+
class B2 extends A2 {
16+
static const B2 element = const B2(0);
17+
const B2(super.foo);
18+
}
19+
class C2 extends A2 {
20+
static const C2 element = const C2(0);
21+
const C2(super.foo);
22+
}
23+
extension type const E2(A2 it) implements A2 {
24+
const E2.pick(bool b) : this(b ? B2.element : C2.element);
25+
}
26+
test2() {}
27+
expectIdentical(expected, actual) {}
28+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class A1 {
2+
const A1(this.foo);
3+
const factory A1.redir(A1 it) = E1.redir;
4+
final int foo;
5+
}
6+
class A2 {
7+
const A2(this.foo);
8+
const factory A2.redir(bool b) = E2.pick;
9+
final int foo;
10+
}
11+
class B2 extends A2 {
12+
const B2(super.foo);
13+
static const B2 element = const B2(0);
14+
}
15+
class C2 extends A2 {
16+
const C2(super.foo);
17+
static const C2 element = const C2(0);
18+
}
19+
expectIdentical(expected, actual) {}
20+
extension type const E1(A1 it) implements A1 {
21+
const factory E1.redir(A1 it) = E1;
22+
}
23+
extension type const E2(A2 it) implements A2 {
24+
const E2.pick(bool b) : this(b ? B2.element : C2.element);
25+
}
26+
main() {}
27+
test1() {}
28+
test2() {}

0 commit comments

Comments
 (0)