[cfe] Refactor super expressions

Change-Id: I9bc0c6cd86316248108440bc367239316bdbc5ac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117150
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
Johnni Winther 2019-09-19 17:17:10 +00:00 committed by commit-bot@chromium.org
parent 5081eb15ee
commit 9ed45651a9
11 changed files with 410 additions and 107 deletions

View file

@ -704,6 +704,7 @@ class PropertyAccessGenerator extends Generator {
..fileOffset = offset;
}
@override
Expression buildCompoundAssignment(Name binaryOperator, Expression value,
{int offset: TreeNode.noOffset,
bool voidContext: false,
@ -1110,6 +1111,18 @@ class SuperPropertyAccessGenerator extends Generator {
@override
String get _plainNameForRead => name.name;
@override
Expression buildSimpleRead() {
return _createRead();
}
Expression _createRead() {
if (getter == null) {
_helper.warnUnresolvedGet(name, fileOffset, isSuper: true);
}
return new SuperPropertyGet(name, getter)..fileOffset = fileOffset;
}
@override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
if (getter == null) {
@ -1124,14 +1137,69 @@ class SuperPropertyAccessGenerator extends Generator {
@override
Expression buildAssignment(Expression value, {bool voidContext = false}) {
return _createWrite(fileOffset, value);
}
Expression _createWrite(int offset, Expression value) {
if (setter == null) {
_helper.warnUnresolvedSet(name, fileOffset, isSuper: true);
_helper.warnUnresolvedSet(name, offset, isSuper: true);
}
SuperPropertySet write = new SuperPropertySet(name, value, setter)
..fileOffset = fileOffset;
..fileOffset = offset;
return write;
}
@override
Expression buildCompoundAssignment(Name binaryOperator, Expression value,
{int offset = TreeNode.noOffset,
bool voidContext = false,
Procedure interfaceTarget,
bool isPreIncDec = false,
bool isPostIncDec = false}) {
MethodInvocation binary = _helper.forest.createMethodInvocation(
offset,
_createRead(),
binaryOperator,
_helper.forest.createArguments(offset, <Expression>[value]),
interfaceTarget: interfaceTarget);
return _createWrite(fileOffset, binary);
}
@override
Expression buildPostfixIncrement(Name binaryOperator,
{int offset = TreeNode.noOffset,
bool voidContext = false,
Procedure interfaceTarget}) {
Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
if (voidContext) {
return buildCompoundAssignment(binaryOperator, value,
offset: offset,
voidContext: voidContext,
interfaceTarget: interfaceTarget,
isPostIncDec: true);
}
VariableDeclaration read = _helper.forest
.createVariableDeclarationForValue(fileOffset, _createRead());
MethodInvocation binary = _helper.forest.createMethodInvocation(
offset,
_helper.createVariableGet(read, fileOffset),
binaryOperator,
_helper.forest.createArguments(offset, <Expression>[value]),
interfaceTarget: interfaceTarget);
VariableDeclaration write = _helper.forest
.createVariableDeclarationForValue(
offset, _createWrite(fileOffset, binary));
return new StaticPostIncDec(read, write)..fileOffset = offset;
}
@override
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
return new IfNullSet(_createRead(), _createWrite(fileOffset, value),
forEffect: voidContext)
..fileOffset = offset;
}
@override
Expression _makeWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {

View file

@ -69,6 +69,8 @@ class InferenceVisitor
return visitPropertyPostIncDec(node, typeContext);
case InternalExpressionKind.StaticPostIncDec:
return visitStaticPostIncDec(node, typeContext);
case InternalExpressionKind.SuperPostIncDec:
return visitSuperPostIncDec(node, typeContext);
}
}
return _unhandledExpression(node, typeContext);
@ -1963,6 +1965,15 @@ class InferenceVisitor
return new ExpressionInferenceResult(inferredType, replacement);
}
ExpressionInferenceResult visitSuperPostIncDec(
SuperPostIncDec node, DartType typeContext) {
inferrer.inferStatement(node.read);
inferrer.inferStatement(node.write);
DartType inferredType = node.read.type;
Expression replacement = node.replace();
return new ExpressionInferenceResult(inferredType, replacement);
}
ExpressionInferenceResult visitLocalPostIncDec(
LocalPostIncDec node, DartType typeContext) {
inferrer.inferStatement(node.read);

View file

@ -193,6 +193,7 @@ enum InternalExpressionKind {
NullAwarePropertySet,
PropertyPostIncDec,
StaticPostIncDec,
SuperPostIncDec,
}
/// Common base class for internal expressions.
@ -1699,11 +1700,11 @@ class IfNullPropertySet extends InternalExpression {
/// An if-null assignment of the form `a ??= b` is, if used for value,
/// encoded as the expression:
///
/// let v1 = o in let v2 = v1.a in v2 == null ? v1.a = b : v2
/// let v1 = a in v1 == null ? a = b : v1
///
/// and, if used for effect, encoded as the expression:
///
/// let v1 = o in v1.a == null ? v1.a = b : null
/// a == null ? a = b : null
///
class IfNullSet extends InternalExpression {
/// The expression that reads the property from [variable].
@ -1854,7 +1855,7 @@ class PropertyPostIncDec extends InternalExpression {
/// An local variable post inc/dec expression of the form `a++` is encoded as
/// the expression:
///
/// let v1 = a in let v2 = a = a + 1 in v1
/// let v1 = a in let v2 = a = v1 + 1 in v1
///
class LocalPostIncDec extends InternalExpression {
/// The expression that reads the local variable.
@ -1905,7 +1906,7 @@ class LocalPostIncDec extends InternalExpression {
/// An local variable post inc/dec expression of the form `a++` is encoded as
/// the expression:
///
/// let v1 = a in let v2 = a = a + 1 in v1
/// let v1 = a in let v2 = a = v1 + 1 in v1
///
class StaticPostIncDec extends InternalExpression {
/// The expression that reads the static member.
@ -1951,6 +1952,57 @@ class StaticPostIncDec extends InternalExpression {
}
}
/// Internal expression representing an static member post inc/dec expression.
///
/// An local variable post inc/dec expression of the form `super.a++` is encoded
/// as the expression:
///
/// let v1 = super.a in let v2 = super.a = v1 + 1 in v1
///
class SuperPostIncDec extends InternalExpression {
/// The expression that reads the static member.
VariableDeclaration read;
/// The expression that writes the result of the binary operation to the
/// static member.
VariableDeclaration write;
SuperPostIncDec(this.read, this.write) {
read?.parent = this;
write?.parent = this;
}
@override
InternalExpressionKind get kind => InternalExpressionKind.SuperPostIncDec;
@override
Expression replace() {
Expression replacement;
replaceWith(
replacement = new Let(read, createLet(write, createVariableGet(read)))
..fileOffset = fileOffset);
return replacement;
}
@override
void visitChildren(Visitor<dynamic> v) {
read?.accept(v);
write?.accept(v);
}
@override
void transformChildren(Transformer v) {
if (read != null) {
read = read.accept<TreeNode>(v);
read?.parent = this;
}
if (write != null) {
write = write.accept<TreeNode>(v);
write?.parent = this;
}
}
}
/// Internal expression representing an index set expression.
///
/// An index set expression of the form `o[a] = b` used for value is encoded as

View file

@ -25,22 +25,52 @@ class Base {
class Test extends Base {
void test() {
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ member += /*@ typeArgs=dynamic */ f();
super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
--super. /*@target=Base::member*/ member;
super. /*@target=Base::member*/ member--;
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::+ */ += /*@ typeArgs=C* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::* */ *= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::& */ &= /*@ typeArgs=A* */ f();
/*@ target=B::- */ --super
. /*@target=Base::member*/ /*@target=Base::member*/ member;
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::- */ --;
var /*@ type=B* */ v1 =
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::+ */ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::* */ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
var /*@ type=B* */ v6 = --super. /*@target=Base::member*/ member;
var /*@ type=B* */ v7 = super. /*@target=Base::member*/ member--;
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::& */ &= /*@ typeArgs=A* */ f();
var /*@ type=B* */ v6 =
/*@ target=B::- */ --super
. /*@target=Base::member*/ /*@target=Base::member*/ member;
var /*@ type=B* */ v7 = super
. /*@ type=B* */ /*@target=Base::member*/ /*@target=Base::member*/
member
/*@ type=B* */ /*@ target=B::- */ --;
}
}

View file

@ -38,15 +38,16 @@ class Test extends self::Base {
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}

View file

@ -38,15 +38,16 @@ class Test extends self::Base {
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}

View file

@ -17,33 +17,70 @@ class Base {
class Test1 extends Base {
void test() {
var /*@ type=int* */ v1 = super. /*@target=Base::intProp*/ intProp = getInt();
var /*@ type=int* */ v1 =
super. /*@target=Base::intProp*/ intProp = getInt();
var /*@ type=int* */ v4 =
super. /*@target=Base::intProp*/ intProp ??= getInt();
var /*@ type=int* */ v7 = super. /*@target=Base::intProp*/ intProp += getInt();
var /*@ type=int* */ v10 = ++super. /*@target=Base::intProp*/ intProp;
var /*@ type=int* */ v11 = super. /*@target=Base::intProp*/ intProp++;
super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
/*@ target=num::==*/ ??= getInt();
var /*@ type=int* */ v7 =
super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
/*@ target=num::+ */ += getInt();
var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp;
var /*@ type=int* */ v11 = super
. /*@ type=int* */ /*@target=Base::intProp*/ /*@target=Base::intProp*/
intProp /*@ type=int* */ /*@ target=num::+ */ ++;
}
}
class Test2 extends Base {
void test() {
var /*@ type=int* */ v1 = super. /*@target=Base::numProp*/ numProp = getInt();
var /*@ type=num* */ v2 = super. /*@target=Base::numProp*/ numProp = getNum();
var /*@ type=int* */ v1 =
super. /*@target=Base::numProp*/ numProp = getInt();
var /*@ type=num* */ v2 =
super. /*@target=Base::numProp*/ numProp = getNum();
var /*@ type=double* */ v3 =
super. /*@target=Base::numProp*/ numProp = getDouble();
var /*@ type=num* */ v4 =
super. /*@target=Base::numProp*/ numProp ??= getInt();
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::==*/ ??= getInt();
var /*@ type=num* */ v5 =
super. /*@target=Base::numProp*/ numProp ??= getNum();
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::==*/ ??= getNum();
var /*@ type=num* */ v6 =
super. /*@target=Base::numProp*/ numProp ??= getDouble();
var /*@ type=num* */ v7 = super. /*@target=Base::numProp*/ numProp += getInt();
var /*@ type=num* */ v8 = super. /*@target=Base::numProp*/ numProp += getNum();
var /*@ type=num* */ v9 =
super. /*@target=Base::numProp*/ numProp += getDouble();
var /*@ type=num* */ v10 = ++super. /*@target=Base::numProp*/ numProp;
var /*@ type=num* */ v11 = super. /*@target=Base::numProp*/ numProp++;
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::==*/ ??= getDouble();
var /*@ type=num* */ v7 =
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::+ */ += getInt();
var /*@ type=num* */ v8 =
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::+ */ += getNum();
var /*@ type=num* */ v9 = super
.
/*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::+ */ += getDouble();
var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp;
var /*@ type=num* */ v11 = super
.
/*@ type=num* */ /*@target=Base::numProp*/ /*@target=Base::numProp*/
numProp
/*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@ -51,16 +88,30 @@ class Test3 extends Base {
void test3() {
var /*@ type=double* */ v3 =
super. /*@target=Base::doubleProp*/ doubleProp = getDouble();
var /*@ type=double* */ v6 =
super. /*@target=Base::doubleProp*/ doubleProp ??= getDouble();
var /*@ type=double* */ v7 =
super. /*@target=Base::doubleProp*/ doubleProp += getInt();
var /*@ type=double* */ v8 =
super. /*@target=Base::doubleProp*/ doubleProp += getNum();
var /*@ type=double* */ v9 =
super. /*@target=Base::doubleProp*/ doubleProp += getDouble();
var /*@ type=double* */ v10 = ++super. /*@target=Base::doubleProp*/ doubleProp;
var /*@ type=double* */ v11 = super. /*@target=Base::doubleProp*/ doubleProp++;
var /*@ type=double* */ v6 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
/*@ target=num::==*/ ??= getDouble();
var /*@ type=double* */ v7 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
/*@ target=double::+ */ += getInt();
var /*@ type=double* */ v8 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
/*@ target=double::+ */ += getNum();
var /*@ type=double* */ v9 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
/*@ target=double::+ */ += getDouble();
var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp;
var /*@ type=double* */ v11 = super
. /*@ type=double* */ /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
doubleProp
/*@ type=double* */ /*@ target=double::+ */ ++;
}
}

View file

@ -25,24 +25,53 @@ class Base {
class Test extends Base {
void test() {
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ member += /*@ typeArgs=dynamic */ f();
super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
--super. /*@target=Base::member*/ member;
super. /*@target=Base::member*/ member--;
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::+ */ += /*@ typeArgs=C* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::* */ *= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::& */ &= /*@ typeArgs=A* */ f();
/*@ target=B::- */ --super
. /*@target=Base::member*/ /*@target=Base::member*/ member;
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::- */ --;
var /*@ type=B* */ v1 =
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
super. /*@target=Base::member*/ member += /*@ typeArgs=dynamic */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::+ */ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::* */ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
var /*@ type=B* */ v6 = --super. /*@target=Base::member*/ member;
var /*@ type=B* */ v7 = super. /*@target=Base::member*/ member--;
super. /*@target=Base::member*/ /*@target=Base::member*/ member
/*@ target=B::& */ &= /*@ typeArgs=A* */ f();
var /*@ type=B* */ v6 = /*@ target=B::- */ --super
.
/*@target=Base::member*/ /*@target=Base::member*/ member;
var /*@ type=B* */ v7 = super
.
/*@ type=B* */ /*@target=Base::member*/ /*@target=Base::member*/
member
/*@ type=B* */ /*@ target=B::- */ --;
}
}

View file

@ -38,16 +38,16 @@ class Test extends self::Base {
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}

View file

@ -38,16 +38,16 @@ class Test extends self::Base {
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}

View file

@ -17,37 +17,79 @@ class Base {
class Test1 extends Base {
void test() {
var /*@ type=int* */ v1 = super. /*@target=Base::intProp*/ intProp = getInt();
var /*@ type=num* */ v2 = super. /*@target=Base::intProp*/ intProp = getNum();
var /*@ type=int* */ v1 =
super. /*@target=Base::intProp*/ intProp = getInt();
var /*@ type=num* */ v2 =
super. /*@target=Base::intProp*/ intProp = getNum();
var /*@ type=int* */ v4 =
super. /*@target=Base::intProp*/ intProp ??= getInt();
super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
/*@ target=num::== */ ??= getInt();
var /*@ type=num* */ v5 =
super. /*@target=Base::intProp*/ intProp ??= getNum();
var /*@ type=int* */ v7 = super. /*@target=Base::intProp*/ intProp += getInt();
var /*@ type=num* */ v8 = super. /*@target=Base::intProp*/ intProp += getNum();
var /*@ type=int* */ v10 = ++super. /*@target=Base::intProp*/ intProp;
var /*@ type=int* */ v11 = super. /*@target=Base::intProp*/ intProp++;
super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
/*@ target=num::== */ ??= getNum();
var /*@ type=int* */ v7 =
super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
/*@ target=num::+ */ += getInt();
var /*@ type=num* */ v8 =
super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
/*@ target=num::+ */ += getNum();
var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp;
var /*@ type=int* */ v11 = super
. /*@ type=int* */ /*@target=Base::intProp*/ /*@target=Base::intProp*/
intProp
/*@ type=int* */ /*@ target=num::+ */ ++;
}
}
class Test2 extends Base {
void test() {
var /*@ type=int* */ v1 = super. /*@target=Base::numProp*/ numProp = getInt();
var /*@ type=num* */ v2 = super. /*@target=Base::numProp*/ numProp = getNum();
var /*@ type=int* */ v1 =
super. /*@target=Base::numProp*/ numProp = getInt();
var /*@ type=num* */ v2 =
super. /*@target=Base::numProp*/ numProp = getNum();
var /*@ type=double* */ v3 =
super. /*@target=Base::numProp*/ numProp = getDouble();
var /*@ type=num* */ v4 =
super. /*@target=Base::numProp*/ numProp ??= getInt();
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::== */ ??= getInt();
var /*@ type=num* */ v5 =
super. /*@target=Base::numProp*/ numProp ??= getNum();
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::== */ ??= getNum();
var /*@ type=num* */ v6 =
super. /*@target=Base::numProp*/ numProp ??= getDouble();
var /*@ type=num* */ v7 = super. /*@target=Base::numProp*/ numProp += getInt();
var /*@ type=num* */ v8 = super. /*@target=Base::numProp*/ numProp += getNum();
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::== */ ??= getDouble();
var /*@ type=num* */ v7 =
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::+ */ += getInt();
var /*@ type=num* */ v8 =
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::+ */ += getNum();
var /*@ type=num* */ v9 =
super. /*@target=Base::numProp*/ numProp += getDouble();
var /*@ type=num* */ v10 = ++super. /*@target=Base::numProp*/ numProp;
var /*@ type=num* */ v11 = super. /*@target=Base::numProp*/ numProp++;
super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
/*@ target=num::+ */ += getDouble();
var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp;
var /*@ type=num* */ v11 = super
. /*@ type=num* */ /*@target=Base::numProp*/ /*@target=Base::numProp*/
numProp /*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@ -55,20 +97,38 @@ class Test3 extends Base {
void test3() {
var /*@ type=num* */ v2 =
super. /*@target=Base::doubleProp*/ doubleProp = getNum();
var /*@ type=double* */ v3 =
super. /*@target=Base::doubleProp*/ doubleProp = getDouble();
var /*@ type=num* */ v5 =
super. /*@target=Base::doubleProp*/ doubleProp ??= getNum();
var /*@ type=double* */ v6 =
super. /*@target=Base::doubleProp*/ doubleProp ??= getDouble();
var /*@ type=double* */ v7 =
super. /*@target=Base::doubleProp*/ doubleProp += getInt();
var /*@ type=double* */ v8 =
super. /*@target=Base::doubleProp*/ doubleProp += getNum();
var /*@ type=double* */ v9 =
super. /*@target=Base::doubleProp*/ doubleProp += getDouble();
var /*@ type=double* */ v10 = ++super. /*@target=Base::doubleProp*/ doubleProp;
var /*@ type=double* */ v11 = super. /*@target=Base::doubleProp*/ doubleProp++;
var /*@ type=num* */ v5 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
/*@ target=num::== */ ??= getNum();
var /*@ type=double* */ v6 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
/*@ target=num::== */ ??= getDouble();
var /*@ type=double* */ v7 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
doubleProp /*@ target=double::+ */ += getInt();
var /*@ type=double* */ v8 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
doubleProp /*@ target=double::+ */ += getNum();
var /*@ type=double* */ v9 = super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
doubleProp /*@ target=double::+ */ += getDouble();
var /*@ type=double* */ v10 =
/*@ target=double::+ */ ++super
. /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
doubleProp;
var /*@ type=double* */ v11 = super
. /*@ type=double* */ /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
doubleProp /*@ type=double* */ /*@ target=double::+ */ ++;
}
}