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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 new VariableGet(tmp)); | 89 new VariableGet(tmp)); |
90 complexAssignment?.nullAwareCombiner = nullAwareCombiner; | 90 complexAssignment?.nullAwareCombiner = nullAwareCombiner; |
91 return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment); | 91 return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment); |
92 } | 92 } |
93 | 93 |
94 /// Returns an [Expression] representing a compound assignment (e.g. `+=`) | 94 /// Returns an [Expression] representing a compound assignment (e.g. `+=`) |
95 /// with the accessor on the LHS and [value] on the RHS. | 95 /// with the accessor on the LHS and [value] on the RHS. |
96 Expression buildCompoundAssignment(Name binaryOperator, Expression value, | 96 Expression buildCompoundAssignment(Name binaryOperator, Expression value, |
97 {int offset: TreeNode.noOffset, | 97 {int offset: TreeNode.noOffset, |
98 bool voidContext: false, | 98 bool voidContext: false, |
99 Procedure interfaceTarget}) { | 99 Procedure interfaceTarget, |
| 100 bool isPreIncDec: false}) { |
100 var complexAssignment = startComplexAssignment(value); | 101 var complexAssignment = startComplexAssignment(value); |
| 102 complexAssignment?.isPreIncDec = isPreIncDec; |
101 var combiner = makeBinary( | 103 var combiner = makeBinary( |
102 _makeRead(complexAssignment), binaryOperator, interfaceTarget, value, | 104 _makeRead(complexAssignment), binaryOperator, interfaceTarget, value, |
103 offset: offset); | 105 offset: offset); |
104 complexAssignment?.combiner = combiner; | 106 complexAssignment?.combiner = combiner; |
105 return _finish(_makeWrite(combiner, voidContext, complexAssignment), | 107 return _finish(_makeWrite(combiner, voidContext, complexAssignment), |
106 complexAssignment); | 108 complexAssignment); |
107 } | 109 } |
108 | 110 |
109 /// Returns an [Expression] representing a pre-increment or pre-decrement | 111 /// Returns an [Expression] representing a pre-increment or pre-decrement |
110 /// of the accessor. | 112 /// of the accessor. |
111 Expression buildPrefixIncrement(Name binaryOperator, | 113 Expression buildPrefixIncrement(Name binaryOperator, |
112 {int offset: TreeNode.noOffset, | 114 {int offset: TreeNode.noOffset, |
113 bool voidContext: false, | 115 bool voidContext: false, |
114 Procedure interfaceTarget}) { | 116 Procedure interfaceTarget}) { |
115 return buildCompoundAssignment(binaryOperator, new IntLiteral(1), | 117 return buildCompoundAssignment(binaryOperator, new IntLiteral(1), |
116 offset: offset, | 118 offset: offset, |
117 voidContext: voidContext, | 119 voidContext: voidContext, |
118 interfaceTarget: interfaceTarget); | 120 interfaceTarget: interfaceTarget, |
| 121 isPreIncDec: true); |
119 } | 122 } |
120 | 123 |
121 /// Returns an [Expression] representing a post-increment or post-decrement | 124 /// Returns an [Expression] representing a post-increment or post-decrement |
122 /// of the accessor. | 125 /// of the accessor. |
123 Expression buildPostfixIncrement(Name binaryOperator, | 126 Expression buildPostfixIncrement(Name binaryOperator, |
124 {int offset: TreeNode.noOffset, | 127 {int offset: TreeNode.noOffset, |
125 bool voidContext: false, | 128 bool voidContext: false, |
126 Procedure interfaceTarget}) { | 129 Procedure interfaceTarget}) { |
127 if (voidContext) { | 130 if (voidContext) { |
128 return buildPrefixIncrement(binaryOperator, | 131 return buildPrefixIncrement(binaryOperator, |
(...skipping 21 matching lines...) Expand all Loading... |
150 KernelComplexAssignment complexAssignment) { | 153 KernelComplexAssignment complexAssignment) { |
151 return _makeWrite(value, voidContext, complexAssignment); | 154 return _makeWrite(value, voidContext, complexAssignment); |
152 } | 155 } |
153 | 156 |
154 Expression _makeRead(KernelComplexAssignment complexAssignment); | 157 Expression _makeRead(KernelComplexAssignment complexAssignment); |
155 | 158 |
156 Expression _makeWrite(Expression value, bool voidContext, | 159 Expression _makeWrite(Expression value, bool voidContext, |
157 KernelComplexAssignment complexAssignment); | 160 KernelComplexAssignment complexAssignment); |
158 | 161 |
159 Expression _finish( | 162 Expression _finish( |
160 Expression body, KernelComplexAssignment complexAssignment) => | 163 Expression body, KernelComplexAssignment complexAssignment) { |
161 body; | 164 if (complexAssignment != null) { |
| 165 complexAssignment.desugared = body; |
| 166 return complexAssignment; |
| 167 } else { |
| 168 return body; |
| 169 } |
| 170 } |
162 | 171 |
163 /// Returns an [Expression] representing a compile-time error. | 172 /// Returns an [Expression] representing a compile-time error. |
164 /// | 173 /// |
165 /// At runtime, an exception will be thrown. | 174 /// At runtime, an exception will be thrown. |
166 makeInvalidRead() { | 175 makeInvalidRead() { |
167 return internalError( | 176 return internalError( |
168 "Unhandled compile-time error.", null, offsetForToken(token)); | 177 "Unhandled compile-time error.", null, offsetForToken(token)); |
169 } | 178 } |
170 | 179 |
171 /// Returns an [Expression] representing a compile-time error wrapping | 180 /// Returns an [Expression] representing a compile-time error wrapping |
(...skipping 16 matching lines...) Expand all Loading... |
188 DartType promotedType; | 197 DartType promotedType; |
189 | 198 |
190 VariableAccessor( | 199 VariableAccessor( |
191 BuilderHelper helper, this.variable, this.promotedType, Token token) | 200 BuilderHelper helper, this.variable, this.promotedType, Token token) |
192 : super(helper, token); | 201 : super(helper, token); |
193 | 202 |
194 Expression _makeRead(KernelComplexAssignment complexAssignment) { | 203 Expression _makeRead(KernelComplexAssignment complexAssignment) { |
195 var fact = helper.typePromoter | 204 var fact = helper.typePromoter |
196 .getFactForAccess(variable, helper.functionNestingLevel); | 205 .getFactForAccess(variable, helper.functionNestingLevel); |
197 var scope = helper.typePromoter.currentScope; | 206 var scope = helper.typePromoter.currentScope; |
198 return new KernelVariableGet(variable, fact, scope) | 207 var read = new KernelVariableGet(variable, fact, scope) |
199 ..fileOffset = offsetForToken(token); | 208 ..fileOffset = offsetForToken(token); |
| 209 complexAssignment?.read = read; |
| 210 return read; |
200 } | 211 } |
201 | 212 |
202 Expression _makeWrite(Expression value, bool voidContext, | 213 Expression _makeWrite(Expression value, bool voidContext, |
203 KernelComplexAssignment complexAssignment) { | 214 KernelComplexAssignment complexAssignment) { |
204 helper.typePromoter.mutateVariable(variable, helper.functionNestingLevel); | 215 helper.typePromoter.mutateVariable(variable, helper.functionNestingLevel); |
205 return variable.isFinal || variable.isConst | 216 var write = variable.isFinal || variable.isConst |
206 ? makeInvalidWrite(value) | 217 ? makeInvalidWrite(value) |
207 : new KernelVariableSet(variable, value) | 218 : new KernelVariableSet(variable, value) |
208 ..fileOffset = offsetForToken(token); | 219 ..fileOffset = offsetForToken(token); |
| 220 complexAssignment?.write = write; |
| 221 return write; |
209 } | 222 } |
210 } | 223 } |
211 | 224 |
212 class PropertyAccessor extends Accessor { | 225 class PropertyAccessor extends Accessor { |
213 VariableDeclaration _receiverVariable; | 226 VariableDeclaration _receiverVariable; |
214 Expression receiver; | 227 Expression receiver; |
215 Name name; | 228 Name name; |
216 Member getter, setter; | 229 Member getter, setter; |
217 | 230 |
218 static Accessor make(BuilderHelper helper, Expression receiver, Name name, | 231 static Accessor make(BuilderHelper helper, Expression receiver, Name name, |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 | 629 |
617 Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) { | 630 Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) { |
618 return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset); | 631 return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset); |
619 } | 632 } |
620 | 633 |
621 VariableDeclaration makeOrReuseVariable(Expression value) { | 634 VariableDeclaration makeOrReuseVariable(Expression value) { |
622 // TODO: Devise a way to remember if a variable declaration was reused | 635 // TODO: Devise a way to remember if a variable declaration was reused |
623 // or is fresh (hence needs a let binding). | 636 // or is fresh (hence needs a let binding). |
624 return new VariableDeclaration.forValue(value); | 637 return new VariableDeclaration.forValue(value); |
625 } | 638 } |
OLD | NEW |