Skip to content

Commit

Permalink
[cfe] Handle extension setters on nullable types
Browse files Browse the repository at this point in the history
Change-Id: I5b36246038f0c7b94c9d317c2273e00ab8e8772e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152500
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
  • Loading branch information
johnniwinther authored and commit-bot@chromium.org committed Jul 8, 2020
1 parent 45af991 commit 233fe72
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,8 @@ class TypeInferrerImpl implements TypeInferrer {
}
if (includeExtensionMethods) {
ObjectAccessTarget target = _findExtensionMember(
receiverBound, coreTypes.objectClass, name, fileOffset);
receiverBound, coreTypes.objectClass, name, fileOffset,
setter: setter);
if (target != null) {
return target;
}
Expand Down
32 changes: 32 additions & 0 deletions pkg/front_end/testcases/nnbd/nullable_setter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2019, 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 C {
String m = "";
void set setter(String v) {}
void operator []=(int index, String value) {}
}

extension on C? {
void set setter(String v) {
this?.m = v;
}

void operator []=(int index, String value) {
this?.m = '$index$value';
}
}

main() {
C? c = new C();
expect("", c?.m);
c.setter = "42";
expect("42", c?.m);
c[42] = "87";
expect("4287", c?.m);
}

expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}
25 changes: 25 additions & 0 deletions pkg/front_end/testcases/nnbd/nullable_setter.dart.outline.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class C extends core::Object {
field core::String m;
synthetic constructor •() → self::C
;
set setter(core::String v) → void
;
operator []=(core::int index, core::String value) → void
;
}
extension _extension#0 on self::C? {
operator []= = self::_extension#0|[]=;
set setter = self::_extension#0|set#setter;
}
static method _extension#0|set#setter(final self::C? #this, core::String v) → void
;
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void
;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;
34 changes: 34 additions & 0 deletions pkg/front_end/testcases/nnbd/nullable_setter.dart.strong.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class C extends core::Object {
field core::String m = "";
synthetic constructor •() → self::C
: super core::Object::•()
;
set setter(core::String v) → void {}
operator []=(core::int index, core::String value) → void {}
}
extension _extension#0 on self::C? {
operator []= = self::_extension#0|[]=;
set setter = self::_extension#0|set#setter;
}
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
}
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
}
static method main() → dynamic {
self::C? c = new self::C::•();
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
self::_extension#0|set#setter(c, "42");
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
self::_extension#0|[]=(c, 42, "87");
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class C extends core::Object {
field core::String m = "";
synthetic constructor •() → self::C
: super core::Object::•()
;
set setter(core::String v) → void {}
operator []=(core::int index, core::String value) → void {}
}
extension _extension#0 on self::C? {
operator []= = self::_extension#0|[]=;
set setter = self::_extension#0|set#setter;
}
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
}
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
}
static method main() → dynamic {
self::C? c = new self::C::•();
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
self::_extension#0|set#setter(c, "42");
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
self::_extension#0|[]=(c, 42, "87");
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class C {
String m = "";
void set setter(String v) { }
void operator []=(int index, String value) { }
}
extension on ;
C;
? { void set setter(String v) { this?.m = v; } void operator []=(int index, String value) { this?.m = '$index$value'; } }
main() { }
expect(expected, actual) { }
34 changes: 34 additions & 0 deletions pkg/front_end/testcases/nnbd/nullable_setter.dart.weak.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class C extends core::Object {
field core::String m = "";
synthetic constructor •() → self::C
: super core::Object::•()
;
set setter(core::String v) → void {}
operator []=(core::int index, core::String value) → void {}
}
extension _extension#0 on self::C? {
operator []= = self::_extension#0|[]=;
set setter = self::_extension#0|set#setter;
}
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
}
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
}
static method main() → dynamic {
self::C? c = new self::C::•();
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
self::_extension#0|set#setter(c, "42");
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
self::_extension#0|[]=(c, 42, "87");
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class C extends core::Object {
field core::String m = "";
synthetic constructor •() → self::C
: super core::Object::•()
;
set setter(core::String v) → void {}
operator []=(core::int index, core::String value) → void {}
}
extension _extension#0 on self::C? {
operator []= = self::_extension#0|[]=;
set setter = self::_extension#0|set#setter;
}
static method _extension#0|set#setter(final self::C? #this, core::String v) → void {
let final self::C? #t1 = #this in #t1.{core::Object::==}(null) ?{core::String?} null : #t1{self::C}.{self::C::m} = v;
}
static method _extension#0|[]=(final self::C? #this, core::int index, core::String value) → void {
let final self::C? #t2 = #this in #t2.{core::Object::==}(null) ?{core::String?} null : #t2{self::C}.{self::C::m} = "${index}${value}";
}
static method main() → dynamic {
self::C? c = new self::C::•();
self::expect("", let final self::C? #t3 = c in #t3.{core::Object::==}(null) ?{core::String?} null : #t3{self::C}.{self::C::m});
self::_extension#0|set#setter(c, "42");
self::expect("42", let final self::C? #t4 = c in #t4.{core::Object::==}(null) ?{core::String?} null : #t4{self::C}.{self::C::m});
self::_extension#0|[]=(c, 42, "87");
self::expect("4287", let final self::C? #t5 = c in #t5.{core::Object::==}(null) ?{core::String?} null : #t5{self::C}.{self::C::m});
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}

0 comments on commit 233fe72

Please sign in to comment.