Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// A library to help transform compounds and null-aware accessors into | 5 /// A library to help transform compounds and null-aware accessors into |
| 6 /// let expressions. | 6 /// let expressions. |
| 7 | 7 |
| 8 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' | 8 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' |
| 9 show | 9 show |
| 10 KernelArguments, | 10 KernelArguments, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 complexAssignment); | 66 complexAssignment); |
| 67 } | 67 } |
| 68 | 68 |
| 69 /// Returns an [Expression] representing a null-aware assignment (`??=`) with | 69 /// Returns an [Expression] representing a null-aware assignment (`??=`) with |
| 70 /// the accessor on the LHS and [value] on the RHS. | 70 /// the accessor on the LHS and [value] on the RHS. |
| 71 /// | 71 /// |
| 72 /// The returned expression evaluates to the assigned value, unless | 72 /// The returned expression evaluates to the assigned value, unless |
| 73 /// [voidContext] is true, in which case it may evaluate to anything. | 73 /// [voidContext] is true, in which case it may evaluate to anything. |
| 74 /// | 74 /// |
| 75 /// [type] is the static type of the RHS. | 75 /// [type] is the static type of the RHS. |
| 76 Expression buildNullAwareAssignment(Expression value, DartType type, | 76 Expression buildNullAwareAssignment( |
| 77 Expression value, DartType type, int offset, | |
| 77 {bool voidContext: false}) { | 78 {bool voidContext: false}) { |
| 78 var complexAssignment = startComplexAssignment(value); | 79 var complexAssignment = startComplexAssignment(value); |
| 79 if (voidContext) { | 80 if (voidContext) { |
| 80 var nullAwareCombiner = new KernelConditionalExpression( | 81 var nullAwareCombiner = new KernelConditionalExpression( |
| 81 buildIsNull(_makeRead(complexAssignment)), | 82 buildIsNull(_makeRead(complexAssignment), offset), |
| 82 _makeWrite(value, false, complexAssignment), | 83 _makeWrite(value, false, complexAssignment), |
| 83 new NullLiteral()); | 84 new NullLiteral()); |
| 84 complexAssignment?.nullAwareCombiner = nullAwareCombiner; | 85 complexAssignment?.nullAwareCombiner = nullAwareCombiner; |
| 85 return _finish(nullAwareCombiner, complexAssignment); | 86 return _finish(nullAwareCombiner, complexAssignment); |
| 86 } | 87 } |
| 87 var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment)); | 88 var tmp = new VariableDeclaration.forValue(_makeRead(complexAssignment)); |
| 88 var nullAwareCombiner = new KernelConditionalExpression( | 89 var nullAwareCombiner = new KernelConditionalExpression( |
| 89 buildIsNull(new VariableGet(tmp)), | 90 buildIsNull(new VariableGet(tmp), offset), |
| 90 _makeWrite(value, false, complexAssignment), | 91 _makeWrite(value, false, complexAssignment), |
| 91 new VariableGet(tmp)); | 92 new VariableGet(tmp)); |
| 92 complexAssignment?.nullAwareCombiner = nullAwareCombiner; | 93 complexAssignment?.nullAwareCombiner = nullAwareCombiner; |
| 93 return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment); | 94 return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment); |
| 94 } | 95 } |
| 95 | 96 |
| 96 /// Returns an [Expression] representing a compound assignment (e.g. `+=`) | 97 /// Returns an [Expression] representing a compound assignment (e.g. `+=`) |
| 97 /// with the accessor on the LHS and [value] on the RHS. | 98 /// with the accessor on the LHS and [value] on the RHS. |
| 98 Expression buildCompoundAssignment(Name binaryOperator, Expression value, | 99 Expression buildCompoundAssignment(Name binaryOperator, Expression value, |
| 99 {int offset: TreeNode.noOffset, | 100 {int offset: TreeNode.noOffset, |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 KernelComplexAssignment complexAssignment) { | 342 KernelComplexAssignment complexAssignment) { |
| 342 var write = new KernelPropertySet(receiverAccess(), name, value, setter) | 343 var write = new KernelPropertySet(receiverAccess(), name, value, setter) |
| 343 ..fileOffset = offsetForToken(token); | 344 ..fileOffset = offsetForToken(token); |
| 344 complexAssignment?.write = write; | 345 complexAssignment?.write = write; |
| 345 return write; | 346 return write; |
| 346 } | 347 } |
| 347 | 348 |
| 348 Expression _finish( | 349 Expression _finish( |
| 349 Expression body, KernelComplexAssignment complexAssignment) { | 350 Expression body, KernelComplexAssignment complexAssignment) { |
| 350 var nullAwareGuard = new KernelConditionalExpression( | 351 var nullAwareGuard = new KernelConditionalExpression( |
| 351 buildIsNull(receiverAccess()), new NullLiteral(), body) | 352 buildIsNull(receiverAccess(), offsetForToken(token)), |
| 353 new NullLiteral(), | |
| 354 body) | |
| 352 ..fileOffset = offsetForToken(token); | 355 ..fileOffset = offsetForToken(token); |
| 353 body = makeLet(receiver, nullAwareGuard); | 356 body = makeLet(receiver, nullAwareGuard); |
| 354 if (complexAssignment != null) { | 357 if (complexAssignment != null) { |
| 355 KernelPropertyAssign kernelPropertyAssign = complexAssignment; | 358 KernelPropertyAssign kernelPropertyAssign = complexAssignment; |
| 356 kernelPropertyAssign.nullAwareGuard = nullAwareGuard; | 359 kernelPropertyAssign.nullAwareGuard = nullAwareGuard; |
| 357 kernelPropertyAssign.desugared = body; | 360 kernelPropertyAssign.desugared = body; |
| 358 return kernelPropertyAssign; | 361 return kernelPropertyAssign; |
| 359 } else { | 362 } else { |
| 360 return body; | 363 return body; |
| 361 } | 364 } |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 | 676 |
| 674 Expression makeBinary( | 677 Expression makeBinary( |
| 675 Expression left, Name operator, Procedure interfaceTarget, Expression right, | 678 Expression left, Name operator, Procedure interfaceTarget, Expression right, |
| 676 {int offset: TreeNode.noOffset}) { | 679 {int offset: TreeNode.noOffset}) { |
| 677 return new KernelMethodInvocation( | 680 return new KernelMethodInvocation( |
| 678 left, operator, new KernelArguments(<Expression>[right]), | 681 left, operator, new KernelArguments(<Expression>[right]), |
| 679 interfaceTarget: interfaceTarget) | 682 interfaceTarget: interfaceTarget) |
| 680 ..fileOffset = offset; | 683 ..fileOffset = offset; |
| 681 } | 684 } |
| 682 | 685 |
| 683 Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) { | 686 Expression buildIsNull(Expression value, int offset) { |
|
Paul Berry
2017/06/12 20:17:23
Note: I changed `offset` to a required argument he
| |
| 684 return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset); | 687 return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset); |
| 685 } | 688 } |
| 686 | 689 |
| 687 VariableDeclaration makeOrReuseVariable(Expression value) { | 690 VariableDeclaration makeOrReuseVariable(Expression value) { |
| 688 // TODO: Devise a way to remember if a variable declaration was reused | 691 // TODO: Devise a way to remember if a variable declaration was reused |
| 689 // or is fresh (hence needs a let binding). | 692 // or is fresh (hence needs a let binding). |
| 690 return new VariableDeclaration.forValue(value); | 693 return new VariableDeclaration.forValue(value); |
| 691 } | 694 } |
| OLD | NEW |