Chromium Code Reviews| Index: pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| index 8c96d393783ad53ba4043da27a4b8a9d02cef848..8b23acdd43189d8c84f16120a6be06240e5fe98d 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart |
| @@ -912,12 +912,10 @@ class KernelIfStatement extends IfStatement implements KernelStatement { |
| /// Concrete shadow object representing an assignment to a target of the form |
| /// `a[b]`. |
| class KernelIndexAssign extends KernelComplexAssignment { |
| - /// The receiver of the assignment target (e.g. `a` in `a[b] = c`), or `null` |
| - /// if there is no receiver. |
| + /// The receiver of the assignment target (e.g. `a` in `a[b] = c`). |
| Expression receiver; |
| - /// In an assignment to an index expression, the index expression, or `null` |
| - /// if this is not an assignment to an index expression. |
| + /// In an assignment to an index expression, the index expression. |
| Expression index; |
| KernelIndexAssign(this.receiver, this.index, Expression rhs) : super(rhs); |
| @@ -1449,6 +1447,64 @@ abstract class KernelStatement extends Statement { |
| void _inferStatement(KernelTypeInferrer inferrer); |
| } |
| +/// Concrete shadow object representing an assignment to a property. |
| +class KernelPropertyAssign extends KernelComplexAssignment { |
| + /// The receiver of the assignment target (e.g. `a` in `a.b = c`), or `null` |
| + /// if there is no receiver (implicit `this`). |
| + Expression receiver; |
| + |
| + /// If this assignment uses null-aware access (`?.`), the conditional |
| + /// expression that guards the access; otherwise `null`. |
| + Expression nullAwareGuard; |
| + |
| + /// Indicates whether this assignment uses `super`. |
| + final bool isSuper; |
| + |
| + KernelPropertyAssign(this.receiver, Expression rhs, {this.isSuper: false}) |
| + : super(rhs); |
| + |
| + @override |
| + List<String> _getToStringParts() { |
| + var parts = super._getToStringParts(); |
| + if (receiver != null) parts.add('receiver=$receiver'); |
| + if (nullAwareGuard != null) parts.add('nullAwareGuard=nullAwareGuard'); |
|
scheglov
2017/06/12 18:19:02
'nullAwareGuard=$nullAwareGuard'
|
| + return parts; |
| + } |
| + |
| + @override |
| + DartType _inferExpression( |
| + KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| + typeNeeded = |
| + inferrer.listener.propertyAssignEnter(desugared, typeContext) || |
| + typeNeeded; |
| + // TODO(paulberry): record the appropriate types on let variables and |
| + // conditional expressions. |
| + DartType receiverType; |
| + if (receiver != null) { |
| + receiverType = inferrer.inferExpression(receiver, null, true); |
| + } else if (isSuper) { |
| + receiverType = inferrer.classHierarchy.getTypeAsInstanceOf( |
| + inferrer.thisType, inferrer.thisType.classNode.supertype.classNode); |
| + } else { |
| + receiverType = inferrer.thisType; |
| + } |
| + if (read != null) { |
| + inferrer.findPropertyGetMember(receiverType, read, silent: true); |
| + } |
| + Member writeMember; |
| + if (write != null) { |
| + writeMember = inferrer.findPropertySetMember(receiverType, write); |
| + } |
| + // To replicate analyzer behavior, we base type inference on the write |
| + // member. TODO(paulberry): would it be better to use the read member when |
| + // doing compound assignment? |
| + var writeContext = writeMember?.setterType; |
| + var inferredType = _inferRhs(inferrer, writeContext); |
| + inferrer.listener.propertyAssignExit(desugared, inferredType); |
| + return inferredType; |
| + } |
| +} |
| + |
| /// Concrete shadow object representing an assignment to a static variable. |
| class KernelStaticAssignment extends KernelComplexAssignment { |
| KernelStaticAssignment(Expression rhs) : super(rhs); |