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, |
11 KernelComplexAssignment, | 11 KernelComplexAssignment, |
12 KernelConditionalExpression, | 12 KernelConditionalExpression, |
13 KernelMethodInvocation, | 13 KernelMethodInvocation, |
| 14 KernelPropertyAssign, |
14 KernelPropertyGet, | 15 KernelPropertyGet, |
15 KernelPropertySet, | 16 KernelPropertySet, |
16 KernelThisExpression, | 17 KernelThisExpression, |
17 KernelVariableDeclaration, | 18 KernelVariableDeclaration, |
18 KernelVariableGet, | 19 KernelVariableGet, |
19 KernelVariableSet; | 20 KernelVariableSet; |
20 | 21 |
21 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; | 22 import 'package:front_end/src/fasta/kernel/utils.dart' show offsetForToken; |
22 | 23 |
23 import 'package:front_end/src/scanner/token.dart' show Token; | 24 import 'package:front_end/src/scanner/token.dart' show Token; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 | 243 |
243 PropertyAccessor.internal(BuilderHelper helper, this.receiver, this.name, | 244 PropertyAccessor.internal(BuilderHelper helper, this.receiver, this.name, |
244 this.getter, this.setter, Token token) | 245 this.getter, this.setter, Token token) |
245 : super(helper, token); | 246 : super(helper, token); |
246 | 247 |
247 Expression _makeSimpleRead() => new KernelPropertyGet(receiver, name, getter) | 248 Expression _makeSimpleRead() => new KernelPropertyGet(receiver, name, getter) |
248 ..fileOffset = offsetForToken(token); | 249 ..fileOffset = offsetForToken(token); |
249 | 250 |
250 Expression _makeSimpleWrite(Expression value, bool voidContext, | 251 Expression _makeSimpleWrite(Expression value, bool voidContext, |
251 KernelComplexAssignment complexAssignment) { | 252 KernelComplexAssignment complexAssignment) { |
252 return new KernelPropertySet(receiver, name, value, setter) | 253 var write = new KernelPropertySet(receiver, name, value, setter) |
253 ..fileOffset = offsetForToken(token); | 254 ..fileOffset = offsetForToken(token); |
| 255 complexAssignment?.write = write; |
| 256 return write; |
254 } | 257 } |
255 | 258 |
256 receiverAccess() { | 259 receiverAccess() { |
257 _receiverVariable ??= new VariableDeclaration.forValue(receiver); | 260 _receiverVariable ??= new VariableDeclaration.forValue(receiver); |
258 return new VariableGet(_receiverVariable) | 261 return new VariableGet(_receiverVariable) |
259 ..fileOffset = offsetForToken(token); | 262 ..fileOffset = offsetForToken(token); |
260 } | 263 } |
261 | 264 |
262 Expression _makeRead(KernelComplexAssignment complexAssignment) => | 265 Expression _makeRead(KernelComplexAssignment complexAssignment) { |
263 new KernelPropertyGet(receiverAccess(), name, getter) | 266 var read = new KernelPropertyGet(receiverAccess(), name, getter) |
264 ..fileOffset = offsetForToken(token); | 267 ..fileOffset = offsetForToken(token); |
| 268 complexAssignment?.read = read; |
| 269 return read; |
| 270 } |
265 | 271 |
266 Expression _makeWrite(Expression value, bool voidContext, | 272 Expression _makeWrite(Expression value, bool voidContext, |
267 KernelComplexAssignment complexAssignment) { | 273 KernelComplexAssignment complexAssignment) { |
268 return new KernelPropertySet(receiverAccess(), name, value, setter) | 274 var write = new KernelPropertySet(receiverAccess(), name, value, setter) |
269 ..fileOffset = offsetForToken(token); | 275 ..fileOffset = offsetForToken(token); |
| 276 complexAssignment?.write = write; |
| 277 return write; |
270 } | 278 } |
271 | 279 |
272 Expression _finish( | 280 Expression _finish( |
273 Expression body, KernelComplexAssignment complexAssignment) => | 281 Expression body, KernelComplexAssignment complexAssignment) { |
274 makeLet(_receiverVariable, body); | 282 body = makeLet(_receiverVariable, body); |
| 283 if (complexAssignment != null) { |
| 284 complexAssignment.desugared = body; |
| 285 return complexAssignment; |
| 286 } else { |
| 287 return body; |
| 288 } |
| 289 } |
275 } | 290 } |
276 | 291 |
277 /// Special case of [PropertyAccessor] to avoid creating an indirect access to | 292 /// Special case of [PropertyAccessor] to avoid creating an indirect access to |
278 /// 'this'. | 293 /// 'this'. |
279 class ThisPropertyAccessor extends Accessor { | 294 class ThisPropertyAccessor extends Accessor { |
280 Name name; | 295 Name name; |
281 Member getter, setter; | 296 Member getter, setter; |
282 | 297 |
283 ThisPropertyAccessor( | 298 ThisPropertyAccessor( |
284 BuilderHelper helper, this.name, this.getter, this.setter, Token token) | 299 BuilderHelper helper, this.name, this.getter, this.setter, Token token) |
285 : super(helper, token); | 300 : super(helper, token); |
286 | 301 |
287 Expression _makeRead(KernelComplexAssignment complexAssignment) => | 302 Expression _makeRead(KernelComplexAssignment complexAssignment) { |
288 new KernelPropertyGet(new KernelThisExpression(), name, getter) | 303 var read = new KernelPropertyGet(new KernelThisExpression(), name, getter) |
289 ..fileOffset = offsetForToken(token); | 304 ..fileOffset = offsetForToken(token); |
| 305 complexAssignment?.read = read; |
| 306 return read; |
| 307 } |
290 | 308 |
291 Expression _makeWrite(Expression value, bool voidContext, | 309 Expression _makeWrite(Expression value, bool voidContext, |
292 KernelComplexAssignment complexAssignment) { | 310 KernelComplexAssignment complexAssignment) { |
293 return new KernelPropertySet( | 311 var write = |
294 new KernelThisExpression(), name, value, setter) | 312 new KernelPropertySet(new KernelThisExpression(), name, value, setter) |
295 ..fileOffset = offsetForToken(token); | 313 ..fileOffset = offsetForToken(token); |
| 314 complexAssignment?.write = write; |
| 315 return write; |
296 } | 316 } |
297 } | 317 } |
298 | 318 |
299 class NullAwarePropertyAccessor extends Accessor { | 319 class NullAwarePropertyAccessor extends Accessor { |
300 VariableDeclaration receiver; | 320 VariableDeclaration receiver; |
| 321 Expression receiverExpression; |
301 Name name; | 322 Name name; |
302 Member getter, setter; | 323 Member getter, setter; |
303 DartType type; | 324 DartType type; |
304 | 325 |
305 NullAwarePropertyAccessor(BuilderHelper helper, Expression receiver, | 326 NullAwarePropertyAccessor(BuilderHelper helper, this.receiverExpression, |
306 this.name, this.getter, this.setter, this.type, Token token) | 327 this.name, this.getter, this.setter, this.type, Token token) |
307 : this.receiver = makeOrReuseVariable(receiver), | 328 : this.receiver = makeOrReuseVariable(receiverExpression), |
308 super(helper, token); | 329 super(helper, token); |
309 | 330 |
310 receiverAccess() => new VariableGet(receiver); | 331 receiverAccess() => new VariableGet(receiver); |
311 | 332 |
312 Expression _makeRead(KernelComplexAssignment complexAssignment) => | 333 Expression _makeRead(KernelComplexAssignment complexAssignment) { |
313 new KernelPropertyGet(receiverAccess(), name, getter); | 334 var read = new KernelPropertyGet(receiverAccess(), name, getter) |
| 335 ..fileOffset = offsetForToken(token); |
| 336 complexAssignment?.read = read; |
| 337 return read; |
| 338 } |
314 | 339 |
315 Expression _makeWrite(Expression value, bool voidContext, | 340 Expression _makeWrite(Expression value, bool voidContext, |
316 KernelComplexAssignment complexAssignment) { | 341 KernelComplexAssignment complexAssignment) { |
317 return new KernelPropertySet(receiverAccess(), name, value, setter); | 342 var write = new KernelPropertySet(receiverAccess(), name, value, setter) |
| 343 ..fileOffset = offsetForToken(token); |
| 344 complexAssignment?.write = write; |
| 345 return write; |
318 } | 346 } |
319 | 347 |
320 Expression _finish( | 348 Expression _finish( |
321 Expression body, KernelComplexAssignment complexAssignment) => | 349 Expression body, KernelComplexAssignment complexAssignment) { |
322 makeLet( | 350 var nullAwareGuard = new KernelConditionalExpression( |
323 receiver, | 351 buildIsNull(receiverAccess()), new NullLiteral(), body) |
324 new KernelConditionalExpression( | 352 ..fileOffset = offsetForToken(token); |
325 buildIsNull(receiverAccess()), new NullLiteral(), body)); | 353 body = makeLet(receiver, nullAwareGuard); |
| 354 if (complexAssignment != null) { |
| 355 KernelPropertyAssign kernelPropertyAssign = complexAssignment; |
| 356 kernelPropertyAssign.nullAwareGuard = nullAwareGuard; |
| 357 kernelPropertyAssign.desugared = body; |
| 358 return kernelPropertyAssign; |
| 359 } else { |
| 360 return body; |
| 361 } |
| 362 } |
326 } | 363 } |
327 | 364 |
328 class SuperPropertyAccessor extends Accessor { | 365 class SuperPropertyAccessor extends Accessor { |
329 Name name; | 366 Name name; |
330 Member getter, setter; | 367 Member getter, setter; |
331 | 368 |
332 SuperPropertyAccessor( | 369 SuperPropertyAccessor( |
333 BuilderHelper helper, this.name, this.getter, this.setter, Token token) | 370 BuilderHelper helper, this.name, this.getter, this.setter, Token token) |
334 : super(helper, token); | 371 : super(helper, token); |
335 | 372 |
336 Expression _makeRead(KernelComplexAssignment complexAssignment) { | 373 Expression _makeRead(KernelComplexAssignment complexAssignment) { |
337 if (getter == null) return makeInvalidRead(); | 374 if (getter == null) return makeInvalidRead(); |
338 // TODO(ahe): Use [DirectPropertyGet] when possible. | 375 // TODO(ahe): Use [DirectPropertyGet] when possible. |
339 return new SuperPropertyGet(name, getter) | 376 var read = new SuperPropertyGet(name, getter) |
340 ..fileOffset = offsetForToken(token); | 377 ..fileOffset = offsetForToken(token); |
| 378 complexAssignment?.read = read; |
| 379 return read; |
341 } | 380 } |
342 | 381 |
343 Expression _makeWrite(Expression value, bool voidContext, | 382 Expression _makeWrite(Expression value, bool voidContext, |
344 KernelComplexAssignment complexAssignment) { | 383 KernelComplexAssignment complexAssignment) { |
345 if (setter == null) return makeInvalidWrite(value); | 384 if (setter == null) return makeInvalidWrite(value); |
346 // TODO(ahe): Use [DirectPropertySet] when possible. | 385 // TODO(ahe): Use [DirectPropertySet] when possible. |
347 return new SuperPropertySet(name, value, setter) | 386 var write = new SuperPropertySet(name, value, setter) |
348 ..fileOffset = offsetForToken(token); | 387 ..fileOffset = offsetForToken(token); |
| 388 complexAssignment?.write = write; |
| 389 return write; |
349 } | 390 } |
350 } | 391 } |
351 | 392 |
352 class IndexAccessor extends Accessor { | 393 class IndexAccessor extends Accessor { |
353 Expression receiver; | 394 Expression receiver; |
354 Expression index; | 395 Expression index; |
355 VariableDeclaration receiverVariable; | 396 VariableDeclaration receiverVariable; |
356 VariableDeclaration indexVariable; | 397 VariableDeclaration indexVariable; |
357 Procedure getter, setter; | 398 Procedure getter, setter; |
358 | 399 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 | 682 |
642 Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) { | 683 Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) { |
643 return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset); | 684 return makeBinary(value, equalsName, null, new NullLiteral(), offset: offset); |
644 } | 685 } |
645 | 686 |
646 VariableDeclaration makeOrReuseVariable(Expression value) { | 687 VariableDeclaration makeOrReuseVariable(Expression value) { |
647 // TODO: Devise a way to remember if a variable declaration was reused | 688 // TODO: Devise a way to remember if a variable declaration was reused |
648 // or is fresh (hence needs a let binding). | 689 // or is fresh (hence needs a let binding). |
649 return new VariableDeclaration.forValue(value); | 690 return new VariableDeclaration.forValue(value); |
650 } | 691 } |
OLD | NEW |