| 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:kernel/ast.dart'; | 8 import 'package:kernel/ast.dart'; |
| 9 | 9 |
| 10 final Name indexGetName = new Name("[]"); | 10 final Name indexGetName = new Name("[]"); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 makeInvalidWrite(Expression value) => wrapInvalid(value); | 138 makeInvalidWrite(Expression value) => wrapInvalid(value); |
| 139 } | 139 } |
| 140 | 140 |
| 141 class VariableAccessor extends Accessor { | 141 class VariableAccessor extends Accessor { |
| 142 VariableDeclaration variable; | 142 VariableDeclaration variable; |
| 143 DartType promotedType; | 143 DartType promotedType; |
| 144 | 144 |
| 145 VariableAccessor(this.variable, this.promotedType, int offset) | 145 VariableAccessor(this.variable, this.promotedType, int offset) |
| 146 : super(offset); | 146 : super(offset); |
| 147 | 147 |
| 148 _makeRead() => new VariableGet(variable, promotedType)..fileOffset = offset; | 148 Expression _makeRead() => |
| 149 new VariableGet(variable, promotedType)..fileOffset = offset; |
| 149 | 150 |
| 150 _makeWrite(Expression value, bool voidContext) { | 151 Expression _makeWrite(Expression value, bool voidContext) { |
| 151 return variable.isFinal || variable.isConst | 152 return variable.isFinal || variable.isConst |
| 152 ? makeInvalidWrite(value) | 153 ? makeInvalidWrite(value) |
| 153 : new VariableSet(variable, value) | 154 : new VariableSet(variable, value) |
| 154 ..fileOffset = offset; | 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( |
| 165 Expression receiver, Name name, Member getter, Member setter, | 166 Expression receiver, Name name, Member getter, Member setter, |
| 166 {int offset: TreeNode.noOffset}) { | 167 {int offset: TreeNode.noOffset}) { |
| 167 if (receiver is ThisExpression) { | 168 if (receiver is ThisExpression) { |
| 168 return new ThisPropertyAccessor(name, getter, setter, offset); | 169 return new ThisPropertyAccessor(name, getter, setter, offset); |
| 169 } else { | 170 } else { |
| 170 return new PropertyAccessor.internal( | 171 return new PropertyAccessor.internal( |
| 171 receiver, name, getter, setter, offset); | 172 receiver, name, getter, setter, offset); |
| 172 } | 173 } |
| 173 } | 174 } |
| 174 | 175 |
| 175 PropertyAccessor.internal( | 176 PropertyAccessor.internal( |
| 176 this.receiver, this.name, this.getter, this.setter, int offset) | 177 this.receiver, this.name, this.getter, this.setter, int offset) |
| 177 : super(offset); | 178 : super(offset); |
| 178 | 179 |
| 179 _makeSimpleRead() => | 180 Expression _makeSimpleRead() => |
| 180 new PropertyGet(receiver, name, getter)..fileOffset = offset; | 181 new PropertyGet(receiver, name, getter)..fileOffset = offset; |
| 181 | 182 |
| 182 _makeSimpleWrite(Expression value, bool voidContext) { | 183 Expression _makeSimpleWrite(Expression value, bool voidContext) { |
| 183 return new PropertySet(receiver, name, value, setter)..fileOffset = offset; | 184 return new PropertySet(receiver, name, value, setter)..fileOffset = offset; |
| 184 } | 185 } |
| 185 | 186 |
| 186 receiverAccess() { | 187 receiverAccess() { |
| 187 _receiverVariable ??= new VariableDeclaration.forValue(receiver); | 188 _receiverVariable ??= new VariableDeclaration.forValue(receiver); |
| 188 return new VariableGet(_receiverVariable)..fileOffset = offset; | 189 return new VariableGet(_receiverVariable)..fileOffset = offset; |
| 189 } | 190 } |
| 190 | 191 |
| 191 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter) | 192 Expression _makeRead() => builtGetter = |
| 192 ..fileOffset = offset; | 193 new PropertyGet(receiverAccess(), name, getter)..fileOffset = offset; |
| 193 | 194 |
| 194 _makeWrite(Expression value, bool voidContext) { | 195 Expression _makeWrite(Expression value, bool voidContext) { |
| 195 return new PropertySet(receiverAccess(), name, value, setter) | 196 return new PropertySet(receiverAccess(), name, value, setter) |
| 196 ..fileOffset = offset; | 197 ..fileOffset = offset; |
| 197 } | 198 } |
| 198 | 199 |
| 199 _finish(Expression body) => makeLet(_receiverVariable, body); | 200 Expression _finish(Expression body) => makeLet(_receiverVariable, body); |
| 200 } | 201 } |
| 201 | 202 |
| 202 /// Special case of [PropertyAccessor] to avoid creating an indirect access to | 203 /// Special case of [PropertyAccessor] to avoid creating an indirect access to |
| 203 /// 'this'. | 204 /// 'this'. |
| 204 class ThisPropertyAccessor extends Accessor { | 205 class ThisPropertyAccessor extends Accessor { |
| 205 Name name; | 206 Name name; |
| 206 Member getter, setter; | 207 Member getter, setter; |
| 207 | 208 |
| 208 ThisPropertyAccessor(this.name, this.getter, this.setter, int offset) | 209 ThisPropertyAccessor(this.name, this.getter, this.setter, int offset) |
| 209 : super(offset); | 210 : super(offset); |
| 210 | 211 |
| 211 _makeRead() => builtGetter = | 212 Expression _makeRead() => builtGetter = |
| 212 new PropertyGet(new ThisExpression(), name, getter)..fileOffset = offset; | 213 new PropertyGet(new ThisExpression(), name, getter)..fileOffset = offset; |
| 213 | 214 |
| 214 _makeWrite(Expression value, bool voidContext) { | 215 Expression _makeWrite(Expression value, bool voidContext) { |
| 215 return new PropertySet(new ThisExpression(), name, value, setter) | 216 return new PropertySet(new ThisExpression(), name, value, setter) |
| 216 ..fileOffset = offset; | 217 ..fileOffset = offset; |
| 217 } | 218 } |
| 218 } | 219 } |
| 219 | 220 |
| 220 class NullAwarePropertyAccessor extends Accessor { | 221 class NullAwarePropertyAccessor extends Accessor { |
| 221 VariableDeclaration receiver; | 222 VariableDeclaration receiver; |
| 222 Name name; | 223 Name name; |
| 223 Member getter, setter; | 224 Member getter, setter; |
| 224 DartType type; | 225 DartType type; |
| 225 | 226 |
| 226 NullAwarePropertyAccessor(Expression receiver, this.name, this.getter, | 227 NullAwarePropertyAccessor(Expression receiver, this.name, this.getter, |
| 227 this.setter, this.type, int offset) | 228 this.setter, this.type, int offset) |
| 228 : this.receiver = makeOrReuseVariable(receiver), | 229 : this.receiver = makeOrReuseVariable(receiver), |
| 229 super(offset); | 230 super(offset); |
| 230 | 231 |
| 231 receiverAccess() => new VariableGet(receiver); | 232 receiverAccess() => new VariableGet(receiver); |
| 232 | 233 |
| 233 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter); | 234 Expression _makeRead() => |
| 235 builtGetter = new PropertyGet(receiverAccess(), name, getter); |
| 234 | 236 |
| 235 _makeWrite(Expression value, bool voidContext) { | 237 Expression _makeWrite(Expression value, bool voidContext) { |
| 236 return new PropertySet(receiverAccess(), name, value, setter); | 238 return new PropertySet(receiverAccess(), name, value, setter); |
| 237 } | 239 } |
| 238 | 240 |
| 239 _finish(Expression body) => makeLet( | 241 Expression _finish(Expression body) => makeLet( |
| 240 receiver, | 242 receiver, |
| 241 new ConditionalExpression( | 243 new ConditionalExpression( |
| 242 buildIsNull(receiverAccess()), new NullLiteral(), body, type)); | 244 buildIsNull(receiverAccess()), new NullLiteral(), body, type)); |
| 243 } | 245 } |
| 244 | 246 |
| 245 class SuperPropertyAccessor extends Accessor { | 247 class SuperPropertyAccessor extends Accessor { |
| 246 Name name; | 248 Name name; |
| 247 Member getter, setter; | 249 Member getter, setter; |
| 248 | 250 |
| 249 SuperPropertyAccessor(this.name, this.getter, this.setter, int offset) | 251 SuperPropertyAccessor(this.name, this.getter, this.setter, int offset) |
| 250 : super(offset); | 252 : super(offset); |
| 251 | 253 |
| 252 _makeRead() { | 254 Expression _makeRead() { |
| 253 if (getter == null) return makeInvalidRead(); | 255 if (getter == null) return makeInvalidRead(); |
| 254 // TODO(ahe): Use [DirectPropertyGet] when possible. | 256 // TODO(ahe): Use [DirectPropertyGet] when possible. |
| 255 return builtGetter = new SuperPropertyGet(name, getter) | 257 return builtGetter = new SuperPropertyGet(name, getter) |
| 256 ..fileOffset = offset; | 258 ..fileOffset = offset; |
| 257 } | 259 } |
| 258 | 260 |
| 259 _makeWrite(Expression value, bool voidContext) { | 261 Expression _makeWrite(Expression value, bool voidContext) { |
| 260 if (setter == null) return makeInvalidWrite(value); | 262 if (setter == null) return makeInvalidWrite(value); |
| 261 // TODO(ahe): Use [DirectPropertySet] when possible. | 263 // TODO(ahe): Use [DirectPropertySet] when possible. |
| 262 return new SuperPropertySet(name, value, setter)..fileOffset = offset; | 264 return new SuperPropertySet(name, value, setter)..fileOffset = offset; |
| 263 } | 265 } |
| 264 } | 266 } |
| 265 | 267 |
| 266 class IndexAccessor extends Accessor { | 268 class IndexAccessor extends Accessor { |
| 267 Expression receiver; | 269 Expression receiver; |
| 268 Expression index; | 270 Expression index; |
| 269 VariableDeclaration receiverVariable; | 271 VariableDeclaration receiverVariable; |
| 270 VariableDeclaration indexVariable; | 272 VariableDeclaration indexVariable; |
| 271 Procedure getter, setter; | 273 Procedure getter, setter; |
| 272 | 274 |
| 273 static Accessor make( | 275 static Accessor make( |
| 274 Expression receiver, Expression index, Procedure getter, Procedure setter, | 276 Expression receiver, Expression index, Procedure getter, Procedure setter, |
| 275 {int offset: TreeNode.noOffset}) { | 277 {int offset: TreeNode.noOffset}) { |
| 276 if (receiver is ThisExpression) { | 278 if (receiver is ThisExpression) { |
| 277 return new ThisIndexAccessor(index, getter, setter, offset); | 279 return new ThisIndexAccessor(index, getter, setter, offset); |
| 278 } else { | 280 } else { |
| 279 return new IndexAccessor.internal( | 281 return new IndexAccessor.internal( |
| 280 receiver, index, getter, setter, offset); | 282 receiver, index, getter, setter, offset); |
| 281 } | 283 } |
| 282 } | 284 } |
| 283 | 285 |
| 284 IndexAccessor.internal( | 286 IndexAccessor.internal( |
| 285 this.receiver, this.index, this.getter, this.setter, int offset) | 287 this.receiver, this.index, this.getter, this.setter, int offset) |
| 286 : super(offset); | 288 : super(offset); |
| 287 | 289 |
| 288 _makeSimpleRead() => new MethodInvocation( | 290 Expression _makeSimpleRead() => new MethodInvocation( |
| 289 receiver, indexGetName, new Arguments(<Expression>[index]), getter) | 291 receiver, indexGetName, new Arguments(<Expression>[index]), getter) |
| 290 ..fileOffset = offset; | 292 ..fileOffset = offset; |
| 291 | 293 |
| 292 _makeSimpleWrite(Expression value, bool voidContext) { | 294 Expression _makeSimpleWrite(Expression value, bool voidContext) { |
| 293 if (!voidContext) return _makeWriteAndReturn(value); | 295 if (!voidContext) return _makeWriteAndReturn(value); |
| 294 return new MethodInvocation(receiver, indexSetName, | 296 return new MethodInvocation(receiver, indexSetName, |
| 295 new Arguments(<Expression>[index, value]), setter) | 297 new Arguments(<Expression>[index, value]), setter) |
| 296 ..fileOffset = offset; | 298 ..fileOffset = offset; |
| 297 } | 299 } |
| 298 | 300 |
| 299 receiverAccess() { | 301 receiverAccess() { |
| 300 // We cannot reuse the receiver if it is a variable since it might be | 302 // We cannot reuse the receiver if it is a variable since it might be |
| 301 // reassigned in the index expression. | 303 // reassigned in the index expression. |
| 302 receiverVariable ??= new VariableDeclaration.forValue(receiver); | 304 receiverVariable ??= new VariableDeclaration.forValue(receiver); |
| 303 return new VariableGet(receiverVariable)..fileOffset = offset; | 305 return new VariableGet(receiverVariable)..fileOffset = offset; |
| 304 } | 306 } |
| 305 | 307 |
| 306 indexAccess() { | 308 indexAccess() { |
| 307 indexVariable ??= new VariableDeclaration.forValue(index); | 309 indexVariable ??= new VariableDeclaration.forValue(index); |
| 308 return new VariableGet(indexVariable)..fileOffset = offset; | 310 return new VariableGet(indexVariable)..fileOffset = offset; |
| 309 } | 311 } |
| 310 | 312 |
| 311 _makeRead() { | 313 Expression _makeRead() { |
| 312 return builtGetter = new MethodInvocation(receiverAccess(), indexGetName, | 314 return builtGetter = new MethodInvocation(receiverAccess(), indexGetName, |
| 313 new Arguments(<Expression>[indexAccess()]), getter) | 315 new Arguments(<Expression>[indexAccess()]), getter) |
| 314 ..fileOffset = offset; | 316 ..fileOffset = offset; |
| 315 } | 317 } |
| 316 | 318 |
| 317 _makeWrite(Expression value, bool voidContext) { | 319 Expression _makeWrite(Expression value, bool voidContext) { |
| 318 if (!voidContext) return _makeWriteAndReturn(value); | 320 if (!voidContext) return _makeWriteAndReturn(value); |
| 319 return new MethodInvocation(receiverAccess(), indexSetName, | 321 return new MethodInvocation(receiverAccess(), indexSetName, |
| 320 new Arguments(<Expression>[indexAccess(), value]), setter) | 322 new Arguments(<Expression>[indexAccess(), value]), setter) |
| 321 ..fileOffset = offset; | 323 ..fileOffset = offset; |
| 322 } | 324 } |
| 323 | 325 |
| 324 // TODO(dmitryas): remove this method after the "[]=" operator of the Context | 326 // TODO(dmitryas): remove this method after the "[]=" operator of the Context |
| 325 // class is made to return a value. | 327 // class is made to return a value. |
| 326 _makeWriteAndReturn(Expression value) { | 328 _makeWriteAndReturn(Expression value) { |
| 327 // The call to []= does not return the value like direct-style assignments | 329 // The call to []= does not return the value like direct-style assignments |
| (...skipping 18 matching lines...) Expand all Loading... |
| 346 /// Special case of [IndexAccessor] to avoid creating an indirect access to | 348 /// Special case of [IndexAccessor] to avoid creating an indirect access to |
| 347 /// 'this'. | 349 /// 'this'. |
| 348 class ThisIndexAccessor extends Accessor { | 350 class ThisIndexAccessor extends Accessor { |
| 349 Expression index; | 351 Expression index; |
| 350 VariableDeclaration indexVariable; | 352 VariableDeclaration indexVariable; |
| 351 Procedure getter, setter; | 353 Procedure getter, setter; |
| 352 | 354 |
| 353 ThisIndexAccessor(this.index, this.getter, this.setter, int offset) | 355 ThisIndexAccessor(this.index, this.getter, this.setter, int offset) |
| 354 : super(offset); | 356 : super(offset); |
| 355 | 357 |
| 356 _makeSimpleRead() { | 358 Expression _makeSimpleRead() { |
| 357 return new MethodInvocation(new ThisExpression(), indexGetName, | 359 return new MethodInvocation(new ThisExpression(), indexGetName, |
| 358 new Arguments(<Expression>[index]), getter); | 360 new Arguments(<Expression>[index]), getter); |
| 359 } | 361 } |
| 360 | 362 |
| 361 _makeSimpleWrite(Expression value, bool voidContext) { | 363 Expression _makeSimpleWrite(Expression value, bool voidContext) { |
| 362 if (!voidContext) return _makeWriteAndReturn(value); | 364 if (!voidContext) return _makeWriteAndReturn(value); |
| 363 return new MethodInvocation(new ThisExpression(), indexSetName, | 365 return new MethodInvocation(new ThisExpression(), indexSetName, |
| 364 new Arguments(<Expression>[index, value]), setter); | 366 new Arguments(<Expression>[index, value]), setter); |
| 365 } | 367 } |
| 366 | 368 |
| 367 indexAccess() { | 369 indexAccess() { |
| 368 indexVariable ??= new VariableDeclaration.forValue(index); | 370 indexVariable ??= new VariableDeclaration.forValue(index); |
| 369 return new VariableGet(indexVariable); | 371 return new VariableGet(indexVariable); |
| 370 } | 372 } |
| 371 | 373 |
| 372 _makeRead() => builtGetter = new MethodInvocation(new ThisExpression(), | 374 Expression _makeRead() => builtGetter = new MethodInvocation( |
| 373 indexGetName, new Arguments(<Expression>[indexAccess()]), getter); | 375 new ThisExpression(), |
| 376 indexGetName, |
| 377 new Arguments(<Expression>[indexAccess()]), |
| 378 getter); |
| 374 | 379 |
| 375 _makeWrite(Expression value, bool voidContext) { | 380 Expression _makeWrite(Expression value, bool voidContext) { |
| 376 if (!voidContext) return _makeWriteAndReturn(value); | 381 if (!voidContext) return _makeWriteAndReturn(value); |
| 377 return new MethodInvocation(new ThisExpression(), indexSetName, | 382 return new MethodInvocation(new ThisExpression(), indexSetName, |
| 378 new Arguments(<Expression>[indexAccess(), value]), setter); | 383 new Arguments(<Expression>[indexAccess(), value]), setter); |
| 379 } | 384 } |
| 380 | 385 |
| 381 _makeWriteAndReturn(Expression value) { | 386 _makeWriteAndReturn(Expression value) { |
| 382 var valueVariable = new VariableDeclaration.forValue(value); | 387 var valueVariable = new VariableDeclaration.forValue(value); |
| 383 var dummy = new VariableDeclaration.forValue(new MethodInvocation( | 388 var dummy = new VariableDeclaration.forValue(new MethodInvocation( |
| 384 new ThisExpression(), | 389 new ThisExpression(), |
| 385 indexSetName, | 390 indexSetName, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 399 Member getter, setter; | 404 Member getter, setter; |
| 400 | 405 |
| 401 SuperIndexAccessor(this.index, this.getter, this.setter, int offset) | 406 SuperIndexAccessor(this.index, this.getter, this.setter, int offset) |
| 402 : super(offset); | 407 : super(offset); |
| 403 | 408 |
| 404 indexAccess() { | 409 indexAccess() { |
| 405 indexVariable ??= new VariableDeclaration.forValue(index); | 410 indexVariable ??= new VariableDeclaration.forValue(index); |
| 406 return new VariableGet(indexVariable); | 411 return new VariableGet(indexVariable); |
| 407 } | 412 } |
| 408 | 413 |
| 409 _makeSimpleRead() => new SuperMethodInvocation( | 414 Expression _makeSimpleRead() => new SuperMethodInvocation( |
| 410 indexGetName, new Arguments(<Expression>[index]), getter); | 415 indexGetName, new Arguments(<Expression>[index]), getter); |
| 411 | 416 |
| 412 _makeSimpleWrite(Expression value, bool voidContext) { | 417 Expression _makeSimpleWrite(Expression value, bool voidContext) { |
| 413 if (!voidContext) return _makeWriteAndReturn(value); | 418 if (!voidContext) return _makeWriteAndReturn(value); |
| 414 return new SuperMethodInvocation( | 419 return new SuperMethodInvocation( |
| 415 indexSetName, new Arguments(<Expression>[index, value]), setter); | 420 indexSetName, new Arguments(<Expression>[index, value]), setter); |
| 416 } | 421 } |
| 417 | 422 |
| 418 _makeRead() { | 423 Expression _makeRead() { |
| 419 return builtGetter = new SuperMethodInvocation( | 424 return builtGetter = new SuperMethodInvocation( |
| 420 indexGetName, new Arguments(<Expression>[indexAccess()]), getter); | 425 indexGetName, new Arguments(<Expression>[indexAccess()]), getter); |
| 421 } | 426 } |
| 422 | 427 |
| 423 _makeWrite(Expression value, bool voidContext) { | 428 Expression _makeWrite(Expression value, bool voidContext) { |
| 424 if (!voidContext) return _makeWriteAndReturn(value); | 429 if (!voidContext) return _makeWriteAndReturn(value); |
| 425 return new SuperMethodInvocation(indexSetName, | 430 return new SuperMethodInvocation(indexSetName, |
| 426 new Arguments(<Expression>[indexAccess(), value]), setter); | 431 new Arguments(<Expression>[indexAccess(), value]), setter); |
| 427 } | 432 } |
| 428 | 433 |
| 429 _makeWriteAndReturn(Expression value) { | 434 _makeWriteAndReturn(Expression value) { |
| 430 var valueVariable = new VariableDeclaration.forValue(value); | 435 var valueVariable = new VariableDeclaration.forValue(value); |
| 431 var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation( | 436 var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation( |
| 432 indexSetName, | 437 indexSetName, |
| 433 new Arguments( | 438 new Arguments( |
| 434 <Expression>[indexAccess(), new VariableGet(valueVariable)]), | 439 <Expression>[indexAccess(), new VariableGet(valueVariable)]), |
| 435 setter)); | 440 setter)); |
| 436 return makeLet( | 441 return makeLet( |
| 437 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); | 442 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); |
| 438 } | 443 } |
| 439 | 444 |
| 440 Expression _finish(Expression body) { | 445 Expression _finish(Expression body) { |
| 441 return makeLet(indexVariable, body); | 446 return makeLet(indexVariable, body); |
| 442 } | 447 } |
| 443 } | 448 } |
| 444 | 449 |
| 445 class StaticAccessor extends Accessor { | 450 class StaticAccessor extends Accessor { |
| 446 Member readTarget; | 451 Member readTarget; |
| 447 Member writeTarget; | 452 Member writeTarget; |
| 448 | 453 |
| 449 StaticAccessor(this.readTarget, this.writeTarget, int offset) : super(offset); | 454 StaticAccessor(this.readTarget, this.writeTarget, int offset) : super(offset); |
| 450 | 455 |
| 451 _makeRead() => builtGetter = | 456 Expression _makeRead() => builtGetter = |
| 452 readTarget == null ? makeInvalidRead() : new StaticGet(readTarget) | 457 readTarget == null ? makeInvalidRead() : new StaticGet(readTarget) |
| 453 ..fileOffset = offset; | 458 ..fileOffset = offset; |
| 454 | 459 |
| 455 _makeWrite(Expression value, bool voidContext) { | 460 Expression _makeWrite(Expression value, bool voidContext) { |
| 456 return writeTarget == null | 461 return writeTarget == null |
| 457 ? makeInvalidWrite(value) | 462 ? makeInvalidWrite(value) |
| 458 : new StaticSet(writeTarget, value) | 463 : new StaticSet(writeTarget, value) |
| 459 ..fileOffset = offset; | 464 ..fileOffset = offset; |
| 460 } | 465 } |
| 461 } | 466 } |
| 462 | 467 |
| 463 class ReadOnlyAccessor extends Accessor { | 468 class ReadOnlyAccessor extends Accessor { |
| 464 Expression expression; | 469 Expression expression; |
| 465 VariableDeclaration value; | 470 VariableDeclaration value; |
| 466 | 471 |
| 467 ReadOnlyAccessor(this.expression, int offset) : super(offset); | 472 ReadOnlyAccessor(this.expression, int offset) : super(offset); |
| 468 | 473 |
| 469 _makeSimpleRead() => expression; | 474 Expression _makeSimpleRead() => expression; |
| 470 | 475 |
| 471 _makeRead() { | 476 Expression _makeRead() { |
| 472 value ??= new VariableDeclaration.forValue(expression); | 477 value ??= new VariableDeclaration.forValue(expression); |
| 473 return new VariableGet(value); | 478 return new VariableGet(value); |
| 474 } | 479 } |
| 475 | 480 |
| 476 _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value); | 481 Expression _makeWrite(Expression value, bool voidContext) => |
| 482 makeInvalidWrite(value); |
| 477 | 483 |
| 478 Expression _finish(Expression body) => makeLet(value, body); | 484 Expression _finish(Expression body) => makeLet(value, body); |
| 479 } | 485 } |
| 480 | 486 |
| 481 Expression makeLet(VariableDeclaration variable, Expression body) { | 487 Expression makeLet(VariableDeclaration variable, Expression body) { |
| 482 if (variable == null) return body; | 488 if (variable == null) return body; |
| 483 return new Let(variable, body); | 489 return new Let(variable, body); |
| 484 } | 490 } |
| 485 | 491 |
| 486 Expression makeBinary( | 492 Expression makeBinary( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 500 | 506 |
| 501 VariableDeclaration makeOrReuseVariable(Expression value) { | 507 VariableDeclaration makeOrReuseVariable(Expression value) { |
| 502 // TODO: Devise a way to remember if a variable declaration was reused | 508 // TODO: Devise a way to remember if a variable declaration was reused |
| 503 // or is fresh (hence needs a let binding). | 509 // or is fresh (hence needs a let binding). |
| 504 return new VariableDeclaration.forValue(value); | 510 return new VariableDeclaration.forValue(value); |
| 505 } | 511 } |
| 506 | 512 |
| 507 Expression wrapInvalid(Expression e) { | 513 Expression wrapInvalid(Expression e) { |
| 508 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); | 514 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); |
| 509 } | 515 } |
| OLD | NEW |