| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 DartType promotedType; | 144 DartType promotedType; |
| 145 | 145 |
| 146 VariableAccessor(this.variable, this.promotedType, int offset) | 146 VariableAccessor(this.variable, this.promotedType, int offset) |
| 147 : super(offset); | 147 : super(offset); |
| 148 | 148 |
| 149 _makeRead() => new VariableGet(variable, promotedType)..fileOffset = offset; | 149 _makeRead() => new VariableGet(variable, promotedType)..fileOffset = offset; |
| 150 | 150 |
| 151 _makeWrite(Expression value, bool voidContext) { | 151 _makeWrite(Expression value, bool voidContext) { |
| 152 return variable.isFinal || variable.isConst | 152 return variable.isFinal || variable.isConst |
| 153 ? makeInvalidWrite(value) | 153 ? makeInvalidWrite(value) |
| 154 : new VariableSet(variable, value)..fileOffset = offset; | 154 : new VariableSet(variable, value) |
| 155 ..fileOffset = offset; |
| 155 } | 156 } |
| 156 } | 157 } |
| 157 | 158 |
| 158 class PropertyAccessor extends Accessor { | 159 class PropertyAccessor extends Accessor { |
| 159 VariableDeclaration _receiverVariable; | 160 VariableDeclaration _receiverVariable; |
| 160 Expression receiver; | 161 Expression receiver; |
| 161 Name name; | 162 Name name; |
| 162 Member getter, setter; | 163 Member getter, setter; |
| 163 | 164 |
| 164 static Accessor make( | 165 static Accessor make( |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 this.receiver, this.index, this.getter, this.setter, int offset) | 286 this.receiver, this.index, this.getter, this.setter, int offset) |
| 286 : super(offset); | 287 : super(offset); |
| 287 | 288 |
| 288 _makeSimpleRead() => new MethodInvocation( | 289 _makeSimpleRead() => new MethodInvocation( |
| 289 receiver, indexGetName, new Arguments(<Expression>[index]), getter) | 290 receiver, indexGetName, new Arguments(<Expression>[index]), getter) |
| 290 ..fileOffset = offset; | 291 ..fileOffset = offset; |
| 291 | 292 |
| 292 _makeSimpleWrite(Expression value, bool voidContext) { | 293 _makeSimpleWrite(Expression value, bool voidContext) { |
| 293 if (!voidContext) return _makeWriteAndReturn(value); | 294 if (!voidContext) return _makeWriteAndReturn(value); |
| 294 return new MethodInvocation(receiver, indexSetName, | 295 return new MethodInvocation(receiver, indexSetName, |
| 295 new Arguments(<Expression>[index, value]), setter)..fileOffset = offset; | 296 new Arguments(<Expression>[index, value]), setter) |
| 297 ..fileOffset = offset; |
| 296 } | 298 } |
| 297 | 299 |
| 298 receiverAccess() { | 300 receiverAccess() { |
| 299 // We cannot reuse the receiver if it is a variable since it might be | 301 // We cannot reuse the receiver if it is a variable since it might be |
| 300 // reassigned in the index expression. | 302 // reassigned in the index expression. |
| 301 receiverVariable ??= new VariableDeclaration.forValue(receiver); | 303 receiverVariable ??= new VariableDeclaration.forValue(receiver); |
| 302 return new VariableGet(receiverVariable)..fileOffset = offset; | 304 return new VariableGet(receiverVariable)..fileOffset = offset; |
| 303 } | 305 } |
| 304 | 306 |
| 305 indexAccess() { | 307 indexAccess() { |
| 306 indexVariable ??= new VariableDeclaration.forValue(index); | 308 indexVariable ??= new VariableDeclaration.forValue(index); |
| 307 return new VariableGet(indexVariable)..fileOffset = offset; | 309 return new VariableGet(indexVariable)..fileOffset = offset; |
| 308 } | 310 } |
| 309 | 311 |
| 310 _makeRead() { | 312 _makeRead() { |
| 311 return builtGetter = new MethodInvocation( | 313 return builtGetter = new MethodInvocation(receiverAccess(), indexGetName, |
| 312 receiverAccess(), | 314 new Arguments(<Expression>[indexAccess()]), getter) |
| 313 indexGetName, | 315 ..fileOffset = offset; |
| 314 new Arguments(<Expression>[indexAccess()]), | |
| 315 getter)..fileOffset = offset; | |
| 316 } | 316 } |
| 317 | 317 |
| 318 _makeWrite(Expression value, bool voidContext) { | 318 _makeWrite(Expression value, bool voidContext) { |
| 319 if (!voidContext) return _makeWriteAndReturn(value); | 319 if (!voidContext) return _makeWriteAndReturn(value); |
| 320 return new MethodInvocation( | 320 return new MethodInvocation(receiverAccess(), indexSetName, |
| 321 receiverAccess(), | 321 new Arguments(<Expression>[indexAccess(), value]), setter) |
| 322 indexSetName, | 322 ..fileOffset = offset; |
| 323 new Arguments(<Expression>[indexAccess(), value]), | |
| 324 setter)..fileOffset = offset; | |
| 325 } | 323 } |
| 326 | 324 |
| 327 // TODO(dmitryas): remove this method after the "[]=" operator of the Context | 325 // TODO(dmitryas): remove this method after the "[]=" operator of the Context |
| 328 // class is made to return a value. | 326 // class is made to return a value. |
| 329 _makeWriteAndReturn(Expression value) { | 327 _makeWriteAndReturn(Expression value) { |
| 330 // The call to []= does not return the value like direct-style assignments | 328 // The call to []= does not return the value like direct-style assignments |
| 331 // do. We need to bind the value in a let. | 329 // do. We need to bind the value in a let. |
| 332 var valueVariable = new VariableDeclaration.forValue(value); | 330 var valueVariable = new VariableDeclaration.forValue(value); |
| 333 var dummy = new VariableDeclaration.forValue(new MethodInvocation( | 331 var dummy = new VariableDeclaration.forValue(new MethodInvocation( |
| 334 receiverAccess(), | 332 receiverAccess(), |
| 335 indexSetName, | 333 indexSetName, |
| 336 new Arguments( | 334 new Arguments( |
| 337 <Expression>[indexAccess(), new VariableGet(valueVariable)]), | 335 <Expression>[indexAccess(), new VariableGet(valueVariable)]), |
| 338 setter)..fileOffset = offset); | 336 setter) |
| 337 ..fileOffset = offset); |
| 339 return makeLet( | 338 return makeLet( |
| 340 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); | 339 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); |
| 341 } | 340 } |
| 342 | 341 |
| 343 Expression _finish(Expression body) { | 342 Expression _finish(Expression body) { |
| 344 return makeLet(receiverVariable, makeLet(indexVariable, body)); | 343 return makeLet(receiverVariable, makeLet(indexVariable, body)); |
| 345 } | 344 } |
| 346 } | 345 } |
| 347 | 346 |
| 348 /// Special case of [IndexAccessor] to avoid creating an indirect access to | 347 /// Special case of [IndexAccessor] to avoid creating an indirect access to |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 return makeLet(indexVariable, body); | 442 return makeLet(indexVariable, body); |
| 444 } | 443 } |
| 445 } | 444 } |
| 446 | 445 |
| 447 class StaticAccessor extends Accessor { | 446 class StaticAccessor extends Accessor { |
| 448 Member readTarget; | 447 Member readTarget; |
| 449 Member writeTarget; | 448 Member writeTarget; |
| 450 | 449 |
| 451 StaticAccessor(this.readTarget, this.writeTarget, int offset) : super(offset); | 450 StaticAccessor(this.readTarget, this.writeTarget, int offset) : super(offset); |
| 452 | 451 |
| 453 _makeRead() => builtGetter = readTarget == null | 452 _makeRead() => builtGetter = |
| 454 ? makeInvalidRead() | 453 readTarget == null ? makeInvalidRead() : new StaticGet(readTarget) |
| 455 : new StaticGet(readTarget)..fileOffset = offset; | 454 ..fileOffset = offset; |
| 456 | 455 |
| 457 _makeWrite(Expression value, bool voidContext) { | 456 _makeWrite(Expression value, bool voidContext) { |
| 458 return writeTarget == null | 457 return writeTarget == null |
| 459 ? makeInvalidWrite(value) | 458 ? makeInvalidWrite(value) |
| 460 : new StaticSet(writeTarget, value)..fileOffset = offset; | 459 : new StaticSet(writeTarget, value) |
| 460 ..fileOffset = offset; |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 | 463 |
| 464 class ReadOnlyAccessor extends Accessor { | 464 class ReadOnlyAccessor extends Accessor { |
| 465 Expression expression; | 465 Expression expression; |
| 466 VariableDeclaration value; | 466 VariableDeclaration value; |
| 467 | 467 |
| 468 ReadOnlyAccessor(this.expression, int offset) : super(offset); | 468 ReadOnlyAccessor(this.expression, int offset) : super(offset); |
| 469 | 469 |
| 470 _makeSimpleRead() => expression; | 470 _makeSimpleRead() => expression; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 501 | 501 |
| 502 VariableDeclaration makeOrReuseVariable(Expression value) { | 502 VariableDeclaration makeOrReuseVariable(Expression value) { |
| 503 // TODO: Devise a way to remember if a variable declaration was reused | 503 // TODO: Devise a way to remember if a variable declaration was reused |
| 504 // or is fresh (hence needs a let binding). | 504 // or is fresh (hence needs a let binding). |
| 505 return new VariableDeclaration.forValue(value); | 505 return new VariableDeclaration.forValue(value); |
| 506 } | 506 } |
| 507 | 507 |
| 508 Expression wrapInvalid(Expression e) { | 508 Expression wrapInvalid(Expression e) { |
| 509 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); | 509 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); |
| 510 } | 510 } |
| OLD | NEW |