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 library kernel.frontend.accessors; | 7 library kernel.frontend.accessors; |
| 8 | 8 |
| 9 import '../ast.dart'; | 9 import '../ast.dart'; |
| 10 | 10 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 return _finish(new ConditionalExpression(buildIsNull(_makeRead()), | 34 return _finish(new ConditionalExpression(buildIsNull(_makeRead()), |
| 35 _makeWrite(value, voidContext), new NullLiteral(), type)); | 35 _makeWrite(value, voidContext), new NullLiteral(), type)); |
| 36 } | 36 } |
| 37 var tmp = new VariableDeclaration.forValue(_makeRead()); | 37 var tmp = new VariableDeclaration.forValue(_makeRead()); |
| 38 return _finish(makeLet( | 38 return _finish(makeLet( |
| 39 tmp, | 39 tmp, |
| 40 new ConditionalExpression(buildIsNull(new VariableGet(tmp)), | 40 new ConditionalExpression(buildIsNull(new VariableGet(tmp)), |
| 41 _makeWrite(value, voidContext), new VariableGet(tmp), type))); | 41 _makeWrite(value, voidContext), new VariableGet(tmp), type))); |
| 42 } | 42 } |
| 43 | 43 |
| 44 Expression buildCompoundAssignment(Name binaryOperator, Expression value, | 44 Expression buildCompoundAssignment( |
| 45 Name binaryOperator, Expression value, int offset, | |
| 45 {bool voidContext: false, Procedure interfaceTarget}) { | 46 {bool voidContext: false, Procedure interfaceTarget}) { |
| 46 return _finish(_makeWrite( | 47 return _finish(_makeWrite( |
| 47 builtBinary = | 48 builtBinary = makeBinary( |
| 48 makeBinary(_makeRead(), binaryOperator, interfaceTarget, value), | 49 _makeRead(), binaryOperator, interfaceTarget, value, offset), |
| 49 voidContext)); | 50 voidContext)); |
| 50 } | 51 } |
| 51 | 52 |
| 52 Expression buildPrefixIncrement(Name binaryOperator, | 53 Expression buildPrefixIncrement(Name binaryOperator, int offset, |
| 53 {bool voidContext: false, Procedure interfaceTarget}) { | 54 {bool voidContext: false, Procedure interfaceTarget}) { |
| 54 return buildCompoundAssignment(binaryOperator, new IntLiteral(1), | 55 return buildCompoundAssignment(binaryOperator, new IntLiteral(1), offset, |
| 55 voidContext: voidContext, interfaceTarget: interfaceTarget); | 56 voidContext: voidContext, interfaceTarget: interfaceTarget); |
| 56 } | 57 } |
| 57 | 58 |
| 58 Expression buildPostfixIncrement(Name binaryOperator, | 59 Expression buildPostfixIncrement(Name binaryOperator, int offset, |
| 59 {bool voidContext: false, Procedure interfaceTarget}) { | 60 {bool voidContext: false, Procedure interfaceTarget}) { |
| 60 if (voidContext) { | 61 if (voidContext) { |
| 61 return buildPrefixIncrement(binaryOperator, | 62 return buildPrefixIncrement(binaryOperator, offset, |
| 62 voidContext: true, interfaceTarget: interfaceTarget); | 63 voidContext: true, interfaceTarget: interfaceTarget); |
| 63 } | 64 } |
| 64 var value = new VariableDeclaration.forValue(_makeRead()); | 65 var value = new VariableDeclaration.forValue(_makeRead()); |
| 65 valueAccess() => new VariableGet(value); | 66 valueAccess() => new VariableGet(value); |
| 66 var dummy = new VariableDeclaration.forValue(_makeWrite( | 67 var dummy = new VariableDeclaration.forValue(_makeWrite( |
| 67 builtBinary = makeBinary( | 68 builtBinary = makeBinary(valueAccess(), binaryOperator, interfaceTarget, |
| 68 valueAccess(), binaryOperator, interfaceTarget, new IntLiteral(1)), | 69 new IntLiteral(1), offset), |
| 69 true)); | 70 true)); |
| 70 return _finish(makeLet(value, makeLet(dummy, valueAccess()))); | 71 return _finish(makeLet(value, makeLet(dummy, valueAccess()))); |
| 71 } | 72 } |
| 72 | 73 |
| 73 Expression _makeSimpleRead() => _makeRead(); | 74 Expression _makeSimpleRead() => _makeRead(); |
| 74 | 75 |
| 75 Expression _makeSimpleWrite(Expression value, bool voidContext) { | 76 Expression _makeSimpleWrite(Expression value, bool voidContext) { |
| 76 return _makeWrite(value, voidContext); | 77 return _makeWrite(value, voidContext); |
| 77 } | 78 } |
| 78 | 79 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 } else { | 116 } else { |
| 116 return new PropertyAccessor._internal(receiver, name, getter, setter); | 117 return new PropertyAccessor._internal(receiver, name, getter, setter); |
| 117 } | 118 } |
| 118 } | 119 } |
| 119 | 120 |
| 120 PropertyAccessor._internal( | 121 PropertyAccessor._internal( |
| 121 this.receiver, this.name, this.getter, this.setter); | 122 this.receiver, this.name, this.getter, this.setter); |
| 122 | 123 |
| 123 _makeSimpleRead() => new PropertyGet(receiver, name, getter); | 124 _makeSimpleRead() => new PropertyGet(receiver, name, getter); |
| 124 _makeSimpleWrite(Expression value, bool voidContext) { | 125 _makeSimpleWrite(Expression value, bool voidContext) { |
| 125 return new PropertySet(receiver, name, value, setter); | 126 return new PropertySet(receiver, name, value, setter); |
|
asgerf
2017/01/04 14:20:01
This node and most other accessor-created nodes ar
jensj
2017/01/05 09:07:55
Yes, I'm not claiming that I won't have to make ch
asgerf
2017/01/05 11:37:41
I just meant that in order to implement the last p
| |
| 126 } | 127 } |
| 127 | 128 |
| 128 receiverAccess() { | 129 receiverAccess() { |
| 129 _receiverVariable ??= new VariableDeclaration.forValue(receiver); | 130 _receiverVariable ??= new VariableDeclaration.forValue(receiver); |
| 130 return new VariableGet(_receiverVariable); | 131 return new VariableGet(_receiverVariable); |
| 131 } | 132 } |
| 132 | 133 |
| 133 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter); | 134 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter); |
| 134 | 135 |
| 135 _makeWrite(Expression value, bool voidContext) { | 136 _makeWrite(Expression value, bool voidContext) { |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 | 395 |
| 395 Expression _finish(Expression body) => makeLet(value, body); | 396 Expression _finish(Expression body) => makeLet(value, body); |
| 396 } | 397 } |
| 397 | 398 |
| 398 Expression makeLet(VariableDeclaration variable, Expression body) { | 399 Expression makeLet(VariableDeclaration variable, Expression body) { |
| 399 if (variable == null) return body; | 400 if (variable == null) return body; |
| 400 return new Let(variable, body); | 401 return new Let(variable, body); |
| 401 } | 402 } |
| 402 | 403 |
| 403 Expression makeBinary(Expression left, Name operator, Procedure interfaceTarget, | 404 Expression makeBinary(Expression left, Name operator, Procedure interfaceTarget, |
| 404 Expression right) { | 405 Expression right, int offset) { |
| 405 return new MethodInvocation( | 406 return new MethodInvocation( |
| 406 left, operator, new Arguments(<Expression>[right]), interfaceTarget); | 407 left, operator, new Arguments(<Expression>[right]), interfaceTarget) |
| 408 ..fileOffset = offset; | |
| 407 } | 409 } |
| 408 | 410 |
| 409 final Name _equalOperator = new Name('=='); | 411 final Name _equalOperator = new Name('=='); |
| 410 | 412 |
| 411 Expression buildIsNull(Expression value) { | 413 Expression buildIsNull(Expression value, {int offset: TreeNode.noOffset}) { |
| 412 return makeBinary(value, _equalOperator, null, new NullLiteral()); | 414 return makeBinary(value, _equalOperator, null, new NullLiteral(), offset); |
| 413 } | 415 } |
| 414 | 416 |
| 415 VariableDeclaration makeOrReuseVariable(Expression value) { | 417 VariableDeclaration makeOrReuseVariable(Expression value) { |
| 416 // TODO: Devise a way to remember if a variable declaration was reused | 418 // TODO: Devise a way to remember if a variable declaration was reused |
| 417 // or is fresh (hence needs a let binding). | 419 // or is fresh (hence needs a let binding). |
| 418 return new VariableDeclaration.forValue(value); | 420 return new VariableDeclaration.forValue(value); |
| 419 } | 421 } |
| 420 | 422 |
| 421 Expression wrapInvalid(Expression e) { | 423 Expression wrapInvalid(Expression e) { |
| 422 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); | 424 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); |
| 423 } | 425 } |
| OLD | NEW |