mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:27:39 +00:00
[cfe] Handle if-null assignment on explicit extension application
Change-Id: I30e02767d23982cb8cae08113bd6b0f97d325e03 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117544 Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
a2a155afd1
commit
bdd432f427
|
@ -144,31 +144,7 @@ abstract class Generator {
|
|||
///
|
||||
/// [type] is the static type of the RHS.
|
||||
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
|
||||
{bool voidContext: false}) {
|
||||
ComplexAssignmentJudgment complexAssignment = startComplexAssignment(value);
|
||||
if (voidContext) {
|
||||
Expression nullAwareCombiner = _forest.createConditionalExpression(
|
||||
buildIsNull(_makeRead(complexAssignment), offset, _helper),
|
||||
null,
|
||||
_makeWrite(value, false, complexAssignment),
|
||||
null,
|
||||
_forest.createNullLiteral(null)..fileOffset = offset)
|
||||
..fileOffset = offset;
|
||||
complexAssignment?.nullAwareCombiner = nullAwareCombiner;
|
||||
return _finish(nullAwareCombiner, complexAssignment);
|
||||
}
|
||||
VariableDeclaration tmp =
|
||||
new VariableDeclaration.forValue(_makeRead(complexAssignment));
|
||||
Expression nullAwareCombiner = _forest.createConditionalExpression(
|
||||
buildIsNull(new VariableGet(tmp), offset, _helper),
|
||||
null,
|
||||
_makeWrite(value, false, complexAssignment),
|
||||
null,
|
||||
new VariableGet(tmp))
|
||||
..fileOffset = offset;
|
||||
complexAssignment?.nullAwareCombiner = nullAwareCombiner;
|
||||
return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
|
||||
}
|
||||
{bool voidContext: false});
|
||||
|
||||
/// Returns a [Expression] representing a compound assignment (e.g. `+=`)
|
||||
/// with the generator on the LHS and [value] on the RHS.
|
||||
|
@ -2210,7 +2186,25 @@ class ExtensionInstanceAccessGenerator extends Generator {
|
|||
|
||||
@override
|
||||
Expression buildSimpleRead() {
|
||||
return _makeRead(null);
|
||||
return _createRead();
|
||||
}
|
||||
|
||||
Expression _createRead() {
|
||||
Expression read;
|
||||
if (readTarget == null) {
|
||||
read = _makeInvalidRead();
|
||||
} else {
|
||||
read = _helper.buildExtensionMethodInvocation(
|
||||
fileOffset,
|
||||
readTarget,
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
fileOffset,
|
||||
_extensionTypeParameterCount,
|
||||
0,
|
||||
_helper.createVariableGet(extensionThis, fileOffset),
|
||||
extensionTypeArguments: _createExtensionTypeArguments()));
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2238,7 +2232,34 @@ class ExtensionInstanceAccessGenerator extends Generator {
|
|||
|
||||
@override
|
||||
Expression buildAssignment(Expression value, {bool voidContext: false}) {
|
||||
return _makeWrite(value, voidContext, null);
|
||||
return _createWrite(fileOffset, value);
|
||||
}
|
||||
|
||||
Expression _createWrite(int offset, Expression value) {
|
||||
Expression write;
|
||||
if (writeTarget == null) {
|
||||
write = _makeInvalidWrite(value);
|
||||
} else {
|
||||
write = _helper.buildExtensionMethodInvocation(
|
||||
offset,
|
||||
writeTarget,
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
offset,
|
||||
_extensionTypeParameterCount,
|
||||
0,
|
||||
_helper.createVariableGet(extensionThis, fileOffset),
|
||||
extensionTypeArguments: _createExtensionTypeArguments(),
|
||||
positionalArguments: [value]));
|
||||
}
|
||||
write.fileOffset = offset;
|
||||
return write;
|
||||
}
|
||||
|
||||
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
|
||||
{bool voidContext: false}) {
|
||||
return new IfNullSet(_createRead(), _createWrite(fileOffset, value),
|
||||
forEffect: voidContext)
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2430,7 +2451,22 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
|
|||
|
||||
@override
|
||||
Expression buildSimpleRead() {
|
||||
return _makeRead(null);
|
||||
return _createRead(receiver);
|
||||
}
|
||||
|
||||
Expression _createRead(Expression receiver) {
|
||||
Expression read;
|
||||
if (readTarget == null) {
|
||||
read = _makeInvalidRead();
|
||||
} else {
|
||||
read = _helper.buildExtensionMethodInvocation(
|
||||
fileOffset,
|
||||
readTarget,
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
fileOffset, extensionTypeParameterCount, 0, receiver,
|
||||
extensionTypeArguments: _createExtensionTypeArguments()));
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2455,7 +2491,37 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
|
|||
|
||||
@override
|
||||
Expression buildAssignment(Expression value, {bool voidContext: false}) {
|
||||
return _makeWrite(value, voidContext, null);
|
||||
return _createWrite(fileOffset, receiver, value);
|
||||
}
|
||||
|
||||
Expression _createWrite(int offset, Expression receiver, Expression value) {
|
||||
Expression write;
|
||||
if (writeTarget == null) {
|
||||
write = _makeInvalidWrite(value);
|
||||
} else {
|
||||
write = _helper.buildExtensionMethodInvocation(
|
||||
offset,
|
||||
writeTarget,
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
offset, extensionTypeParameterCount, 0, receiver,
|
||||
extensionTypeArguments: _createExtensionTypeArguments(),
|
||||
positionalArguments: [value]));
|
||||
}
|
||||
write.fileOffset = offset;
|
||||
return write;
|
||||
}
|
||||
|
||||
@override
|
||||
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
|
||||
{bool voidContext: false}) {
|
||||
VariableDeclaration variable = _helper.forest
|
||||
.createVariableDeclarationForValue(receiver.fileOffset, receiver);
|
||||
Expression read =
|
||||
_createRead(_helper.createVariableGet(variable, receiver.fileOffset));
|
||||
Expression write = _createWrite(fileOffset,
|
||||
_helper.createVariableGet(variable, receiver.fileOffset), value);
|
||||
return new IfNullPropertySet(variable, read, write, forEffect: voidContext)
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -12,6 +12,12 @@ extension Extension on Class {
|
|||
field = value;
|
||||
}
|
||||
int method() => field;
|
||||
|
||||
testImplicitThis() {
|
||||
expect(null, property);
|
||||
expect(42, property ??= 42);
|
||||
expect(42, property ??= 87);
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
|
@ -27,9 +33,35 @@ main() {
|
|||
expect(null, tearOff());
|
||||
expect(42, c?.property = 42);
|
||||
expect(42, tearOff());
|
||||
|
||||
expect(null, c?.property = null);
|
||||
expect(42, c?.property = 42);
|
||||
|
||||
c?.property = null;
|
||||
expect(null, c?.property);
|
||||
expect(42, c.property ??= 42);
|
||||
expect(42, c.property ??= 87);
|
||||
|
||||
expect(null, c?.property = null);
|
||||
c.property ??= 42;
|
||||
expect(42, c?.property);
|
||||
c.property ??= 87;
|
||||
expect(42, c?.property);
|
||||
|
||||
c?.property = null;
|
||||
expect(null, c?.property);
|
||||
expect(42, Extension(c).property ??= 42);
|
||||
expect(42, Extension(c).property ??= 87);
|
||||
|
||||
c?.property = null;
|
||||
expect(null, c?.property);
|
||||
Extension(c).property ??= 42;
|
||||
expect(42, c?.property);
|
||||
Extension(c).property ??= 87;
|
||||
expect(42, c?.property);
|
||||
|
||||
c?.property = null;
|
||||
c.testImplicitThis();
|
||||
}
|
||||
|
||||
expect(expected, actual) {
|
||||
|
|
|
@ -11,6 +11,8 @@ extension Extension on self::Class* {
|
|||
get property = self::Extension|get#property;
|
||||
method method = self::Extension|method;
|
||||
tearoff method = self::Extension|get#method;
|
||||
method testImplicitThis = self::Extension|testImplicitThis;
|
||||
tearoff testImplicitThis = self::Extension|get#testImplicitThis;
|
||||
set property = self::Extension|set#property;
|
||||
}
|
||||
static method Extension|get#property(final self::Class* #this) → core::int*
|
||||
|
@ -21,6 +23,10 @@ static method Extension|method(final self::Class* #this) → core::int*
|
|||
;
|
||||
static method Extension|get#method(final self::Class* #this) → () →* core::int*
|
||||
return () → core::int* => self::Extension|method(#this);
|
||||
static method Extension|testImplicitThis(final self::Class* #this) → dynamic
|
||||
;
|
||||
static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
|
||||
return () → dynamic => self::Extension|testImplicitThis(#this);
|
||||
static method main() → dynamic
|
||||
;
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic
|
||||
|
|
|
@ -12,6 +12,8 @@ extension Extension on self::Class* {
|
|||
get property = self::Extension|get#property;
|
||||
method method = self::Extension|method;
|
||||
tearoff method = self::Extension|get#method;
|
||||
method testImplicitThis = self::Extension|testImplicitThis;
|
||||
tearoff testImplicitThis = self::Extension|get#testImplicitThis;
|
||||
set property = self::Extension|set#property;
|
||||
}
|
||||
static method Extension|get#property(final self::Class* #this) → core::int*
|
||||
|
@ -25,22 +27,49 @@ static method Extension|method(final self::Class* #this) → core::int*
|
|||
return #this.{self::Class::field};
|
||||
static method Extension|get#method(final self::Class* #this) → () →* core::int*
|
||||
return () → core::int* => self::Extension|method(#this);
|
||||
static method Extension|testImplicitThis(final self::Class* #this) → dynamic {
|
||||
self::expect(null, self::Extension|get#property(#this));
|
||||
self::expect(42, let final core::int* #t2 = self::Extension|get#property(#this) in #t2.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#this, 42) : #t2);
|
||||
self::expect(42, let final core::int* #t3 = self::Extension|get#property(#this) in #t3.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#this, 87) : #t3);
|
||||
}
|
||||
static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
|
||||
return () → dynamic => self::Extension|testImplicitThis(#this);
|
||||
static method main() → dynamic {
|
||||
self::Class* c;
|
||||
self::expect(null, let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2));
|
||||
self::expect(null, let final self::Class* #t3 = c in #t3.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t3));
|
||||
self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t4));
|
||||
self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, 42));
|
||||
self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t4));
|
||||
self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t5));
|
||||
self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t6));
|
||||
self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t7, 42));
|
||||
c = new self::Class::•();
|
||||
self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t6));
|
||||
self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t7));
|
||||
() →* core::int* tearOff = let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8);
|
||||
self::expect(null, let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t8));
|
||||
self::expect(null, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t9));
|
||||
() →* core::int* tearOff = let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t10);
|
||||
self::expect(null, tearOff.call());
|
||||
self::expect(42, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t9, 42));
|
||||
self::expect(42, let final self::Class* #t11 = c in #t11.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t11, 42));
|
||||
self::expect(42, tearOff.call());
|
||||
self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t10, null));
|
||||
self::expect(42, let final self::Class* #t11 = c in let final core::int* #t12 = self::Extension|get#property(#t11) in #t12.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t11, 42) : #t12);
|
||||
self::expect(42, let final self::Class* #t13 = c in let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t13, 87) : #t14);
|
||||
self::expect(null, let final self::Class* #t12 = c in #t12.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t12, null));
|
||||
self::expect(42, let final self::Class* #t13 = c in #t13.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t13, 42));
|
||||
let final self::Class* #t14 = c in #t14.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t14, null);
|
||||
self::expect(null, let final self::Class* #t15 = c in #t15.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t15));
|
||||
self::expect(42, let final self::Class* #t16 = c in let final core::int* #t17 = self::Extension|get#property(#t16) in #t17.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t16, 42) : #t17);
|
||||
self::expect(42, let final self::Class* #t18 = c in let final core::int* #t19 = self::Extension|get#property(#t18) in #t19.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t18, 87) : #t19);
|
||||
self::expect(null, let final self::Class* #t20 = c in #t20.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t20, null));
|
||||
let final self::Class* #t21 = c in self::Extension|get#property(#t21).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t21, 42) : null;
|
||||
self::expect(42, let final self::Class* #t22 = c in #t22.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t22));
|
||||
let final self::Class* #t23 = c in self::Extension|get#property(#t23).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t23, 87) : null;
|
||||
self::expect(42, let final self::Class* #t24 = c in #t24.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t24));
|
||||
let final self::Class* #t25 = c in #t25.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t25, null);
|
||||
self::expect(null, let final self::Class* #t26 = c in #t26.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t26));
|
||||
self::expect(42, let final self::Class* #t27 = c in let final core::int* #t28 = self::Extension|get#property(#t27) in #t28.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t27, 42) : #t28);
|
||||
self::expect(42, let final self::Class* #t29 = c in let final core::int* #t30 = self::Extension|get#property(#t29) in #t30.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t29, 87) : #t30);
|
||||
let final self::Class* #t31 = c in #t31.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t31, null);
|
||||
self::expect(null, let final self::Class* #t32 = c in #t32.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t32));
|
||||
let final self::Class* #t33 = c in self::Extension|get#property(#t33).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t33, 42) : null;
|
||||
self::expect(42, let final self::Class* #t34 = c in #t34.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t34));
|
||||
let final self::Class* #t35 = c in self::Extension|get#property(#t35).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t35, 87) : null;
|
||||
self::expect(42, let final self::Class* #t36 = c in #t36.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t36));
|
||||
let final self::Class* #t37 = c in #t37.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t37, null);
|
||||
self::Extension|testImplicitThis(c);
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
|
|
|
@ -12,6 +12,8 @@ extension Extension on self::Class* {
|
|||
get property = self::Extension|get#property;
|
||||
method method = self::Extension|method;
|
||||
tearoff method = self::Extension|get#method;
|
||||
method testImplicitThis = self::Extension|testImplicitThis;
|
||||
tearoff testImplicitThis = self::Extension|get#testImplicitThis;
|
||||
set property = self::Extension|set#property;
|
||||
}
|
||||
static method Extension|get#property(final self::Class* #this) → core::int*
|
||||
|
@ -25,22 +27,49 @@ static method Extension|method(final self::Class* #this) → core::int*
|
|||
return #this.{self::Class::field};
|
||||
static method Extension|get#method(final self::Class* #this) → () →* core::int*
|
||||
return () → core::int* => self::Extension|method(#this);
|
||||
static method Extension|testImplicitThis(final self::Class* #this) → dynamic {
|
||||
self::expect(null, self::Extension|get#property(#this));
|
||||
self::expect(42, let final core::int* #t2 = self::Extension|get#property(#this) in #t2.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#this, 42) : #t2);
|
||||
self::expect(42, let final core::int* #t3 = self::Extension|get#property(#this) in #t3.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#this, 87) : #t3);
|
||||
}
|
||||
static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
|
||||
return () → dynamic => self::Extension|testImplicitThis(#this);
|
||||
static method main() → dynamic {
|
||||
self::Class* c;
|
||||
self::expect(null, let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2));
|
||||
self::expect(null, let final self::Class* #t3 = c in #t3.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t3));
|
||||
self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t4));
|
||||
self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, 42));
|
||||
self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t4));
|
||||
self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t5));
|
||||
self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t6));
|
||||
self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t7, 42));
|
||||
c = new self::Class::•();
|
||||
self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t6));
|
||||
self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t7));
|
||||
() →* core::int* tearOff = let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8);
|
||||
self::expect(null, let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t8));
|
||||
self::expect(null, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t9));
|
||||
() →* core::int* tearOff = let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t10);
|
||||
self::expect(null, tearOff.call());
|
||||
self::expect(42, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t9, 42));
|
||||
self::expect(42, let final self::Class* #t11 = c in #t11.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t11, 42));
|
||||
self::expect(42, tearOff.call());
|
||||
self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t10, null));
|
||||
self::expect(42, let final self::Class* #t11 = c in let final core::int* #t12 = self::Extension|get#property(#t11) in #t12.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t11, 42) : #t12);
|
||||
self::expect(42, let final self::Class* #t13 = c in let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t13, 87) : #t14);
|
||||
self::expect(null, let final self::Class* #t12 = c in #t12.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t12, null));
|
||||
self::expect(42, let final self::Class* #t13 = c in #t13.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t13, 42));
|
||||
let final self::Class* #t14 = c in #t14.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t14, null);
|
||||
self::expect(null, let final self::Class* #t15 = c in #t15.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t15));
|
||||
self::expect(42, let final self::Class* #t16 = c in let final core::int* #t17 = self::Extension|get#property(#t16) in #t17.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t16, 42) : #t17);
|
||||
self::expect(42, let final self::Class* #t18 = c in let final core::int* #t19 = self::Extension|get#property(#t18) in #t19.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t18, 87) : #t19);
|
||||
self::expect(null, let final self::Class* #t20 = c in #t20.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t20, null));
|
||||
let final self::Class* #t21 = c in self::Extension|get#property(#t21).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t21, 42) : null;
|
||||
self::expect(42, let final self::Class* #t22 = c in #t22.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t22));
|
||||
let final self::Class* #t23 = c in self::Extension|get#property(#t23).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t23, 87) : null;
|
||||
self::expect(42, let final self::Class* #t24 = c in #t24.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t24));
|
||||
let final self::Class* #t25 = c in #t25.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t25, null);
|
||||
self::expect(null, let final self::Class* #t26 = c in #t26.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t26));
|
||||
self::expect(42, let final self::Class* #t27 = c in let final core::int* #t28 = self::Extension|get#property(#t27) in #t28.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t27, 42) : #t28);
|
||||
self::expect(42, let final self::Class* #t29 = c in let final core::int* #t30 = self::Extension|get#property(#t29) in #t30.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t29, 87) : #t30);
|
||||
let final self::Class* #t31 = c in #t31.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t31, null);
|
||||
self::expect(null, let final self::Class* #t32 = c in #t32.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t32));
|
||||
let final self::Class* #t33 = c in self::Extension|get#property(#t33).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t33, 42) : null;
|
||||
self::expect(42, let final self::Class* #t34 = c in #t34.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t34));
|
||||
let final self::Class* #t35 = c in self::Extension|get#property(#t35).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t35, 87) : null;
|
||||
self::expect(42, let final self::Class* #t36 = c in #t36.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t36));
|
||||
let final self::Class* #t37 = c in #t37.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t37, null);
|
||||
self::Extension|testImplicitThis(c);
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
pkg/front_end/testcases/extensions/null_aware.dart:23:5: Context: Write to c@408
|
||||
pkg/front_end/testcases/extensions/null_aware.dart:29:5: Context: Write to c@530
|
||||
c = new Class();
|
||||
^
|
||||
|
|
Loading…
Reference in a new issue