Skip to content

Commit 233fe72

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Handle extension setters on nullable types
Change-Id: I5b36246038f0c7b94c9d317c2273e00ab8e8772e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152500 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Dmitry Stefantsov <[email protected]>
1 parent 45af991 commit 233fe72

8 files changed

+205
-1
lines changed

pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,8 @@ class TypeInferrerImpl implements TypeInferrer {
845845
}
846846
if (includeExtensionMethods) {
847847
ObjectAccessTarget target = _findExtensionMember(
848-
receiverBound, coreTypes.objectClass, name, fileOffset);
848+
receiverBound, coreTypes.objectClass, name, fileOffset,
849+
setter: setter);
849850
if (target != null) {
850851
return target;
851852
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2019, 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 C {
6+
String m = "";
7+
void set setter(String v) {}
8+
void operator []=(int index, String value) {}
9+
}
10+
11+
extension on C? {
12+
void set setter(String v) {
13+
this?.m = v;
14+
}
15+
16+
void operator []=(int index, String value) {
17+
this?.m = '$index$value';
18+
}
19+
}
20+
21+
main() {
22+
C? c = new C();
23+
expect("", c?.m);
24+
c.setter = "42";
25+
expect("42", c?.m);
26+
c[42] = "87";
27+
expect("4287", c?.m);
28+
}
29+
30+
expect(expected, actual) {
31+
if (expected != actual) throw 'Expected $expected, actual $actual';
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::String m;
7+
synthetic constructor •() → self::C
8+
;
9+
set setter(core::String v) → void
10+
;
11+
operator []=(core::int index, core::String value) → void
12+
;
13+
}
14+
extension _extension#0 on self::C? {
15+
operator []= = self::_extension#0|[]=;
16+
set setter = self::_extension#0|set#setter;
17+
}
18+
static method _extension#0|set#setter(final self::C? #this, core::String v) → void
19+
;
20+
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void
21+
;
22+
static method main() → dynamic
23+
;
24+
static method expect(dynamic expected, dynamic actual) → dynamic
25+
;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::String m = "";
7+
synthetic constructor •() → self::C
8+
: super core::Object::•()
9+
;
10+
set setter(core::String v) → void {}
11+
operator []=(core::int index, core::String value) → void {}
12+
}
13+
extension _extension#0 on self::C? {
14+
operator []= = self::_extension#0|[]=;
15+
set setter = self::_extension#0|set#setter;
16+
}
17+
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
18+
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
19+
}
20+
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
21+
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
22+
}
23+
static method main() → dynamic {
24+
self::C? c = new self::C::•();
25+
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
26+
self::_extension#0|set#setter(c, "42");
27+
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
28+
self::_extension#0|[]=(c, 42, "87");
29+
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
30+
}
31+
static method expect(dynamic expected, dynamic actual) → dynamic {
32+
if(!expected.{core::Object::==}(actual))
33+
throw "Expected ${expected}, actual ${actual}";
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::String m = "";
7+
synthetic constructor •() → self::C
8+
: super core::Object::•()
9+
;
10+
set setter(core::String v) → void {}
11+
operator []=(core::int index, core::String value) → void {}
12+
}
13+
extension _extension#0 on self::C? {
14+
operator []= = self::_extension#0|[]=;
15+
set setter = self::_extension#0|set#setter;
16+
}
17+
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
18+
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
19+
}
20+
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
21+
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
22+
}
23+
static method main() → dynamic {
24+
self::C? c = new self::C::•();
25+
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
26+
self::_extension#0|set#setter(c, "42");
27+
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
28+
self::_extension#0|[]=(c, 42, "87");
29+
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
30+
}
31+
static method expect(dynamic expected, dynamic actual) → dynamic {
32+
if(!expected.{core::Object::==}(actual))
33+
throw "Expected ${expected}, actual ${actual}";
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class C {
2+
String m = "";
3+
void set setter(String v) { }
4+
void operator []=(int index, String value) { }
5+
}
6+
extension on ;
7+
C;
8+
? { void set setter(String v) { this?.m = v; } void operator []=(int index, String value) { this?.m = '$index$value'; } }
9+
main() { }
10+
expect(expected, actual) { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::String m = "";
7+
synthetic constructor •() → self::C
8+
: super core::Object::•()
9+
;
10+
set setter(core::String v) → void {}
11+
operator []=(core::int index, core::String value) → void {}
12+
}
13+
extension _extension#0 on self::C? {
14+
operator []= = self::_extension#0|[]=;
15+
set setter = self::_extension#0|set#setter;
16+
}
17+
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
18+
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
19+
}
20+
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
21+
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
22+
}
23+
static method main() → dynamic {
24+
self::C? c = new self::C::•();
25+
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
26+
self::_extension#0|set#setter(c, "42");
27+
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
28+
self::_extension#0|[]=(c, 42, "87");
29+
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
30+
}
31+
static method expect(dynamic expected, dynamic actual) → dynamic {
32+
if(!expected.{core::Object::==}(actual))
33+
throw "Expected ${expected}, actual ${actual}";
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::String m = "";
7+
synthetic constructor •() → self::C
8+
: super core::Object::•()
9+
;
10+
set setter(core::String v) → void {}
11+
operator []=(core::int index, core::String value) → void {}
12+
}
13+
extension _extension#0 on self::C? {
14+
operator []= = self::_extension#0|[]=;
15+
set setter = self::_extension#0|set#setter;
16+
}
17+
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
18+
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
19+
}
20+
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
21+
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
22+
}
23+
static method main() → dynamic {
24+
self::C? c = new self::C::•();
25+
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
26+
self::_extension#0|set#setter(c, "42");
27+
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
28+
self::_extension#0|[]=(c, 42, "87");
29+
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
30+
}
31+
static method expect(dynamic expected, dynamic actual) → dynamic {
32+
if(!expected.{core::Object::==}(actual))
33+
throw "Expected ${expected}, actual ${actual}";
34+
}

0 commit comments

Comments
 (0)