Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: pkg/kernel/lib/frontend/accessors.dart

Issue 2777883002: Remove Fasta's copy of accessors.dart. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 final Name indexGetName = new Name("[]");
12
13 final Name indexSetName = new Name("[]=");
14
15 /// An [Accessor] represents a subexpression for which we can't yet build a
16 /// kernel [Expression] because we don't yet know the context in which it is
17 /// used.
18 ///
19 /// Once the context is known, an [Accessor] can be converted into an
20 /// [Expression] by calling a "build" method.
21 ///
22 /// For example, when building a kernel representation for `a[x] = b`, after
23 /// parsing `a[x]` but before parsing `= b`, we don't yet know whether to
24 /// generate an invocation of `operator[]` or `operator[]=`, so we generate an
25 /// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be
26 /// called.
11 abstract class Accessor { 27 abstract class Accessor {
28 final int offset;
29
12 // [builtBinary] and [builtGetter] capture the inner nodes. Used by 30 // [builtBinary] and [builtGetter] capture the inner nodes. Used by
13 // dart2js+rasta for determining how subexpressions map to legacy dart2js Ast 31 // dart2js+rasta for determining how subexpressions map to legacy dart2js Ast
14 // nodes. This will be removed once dart2js type analysis (aka inference) is 32 // nodes. This will be removed once dart2js type analysis (aka inference) is
15 // reimplemented on kernel. 33 // reimplemented on kernel.
16 Expression builtBinary; 34 Expression builtBinary;
17 Expression builtGetter; 35 Expression builtGetter;
18 36
37 Accessor(this.offset);
38
39 /// Builds an [Expression] representing a read from the accessor.
19 Expression buildSimpleRead() { 40 Expression buildSimpleRead() {
20 return _finish(_makeSimpleRead()); 41 return _finish(_makeSimpleRead());
21 } 42 }
22 43
23 /// Returns an assignment to the accessor. 44 /// Builds an [Expression] representing an assignment with the accessor on
45 /// the LHS and [value] on the RHS.
24 /// 46 ///
25 /// The returned expression evaluates to the assigned value, unless 47 /// The returned expression evaluates to the assigned value, unless
26 /// [voidContext] is true, in which case it may evaluate to anything. 48 /// [voidContext] is true, in which case it may evaluate to anything.
27 Expression buildAssignment(Expression value, {bool voidContext: false}) { 49 Expression buildAssignment(Expression value, {bool voidContext: false}) {
28 return _finish(_makeSimpleWrite(value, voidContext)); 50 return _finish(_makeSimpleWrite(value, voidContext));
29 } 51 }
30 52
53 /// Returns an [Expression] representing a null-aware assignment (`??=`) with
54 /// the accessor on the LHS and [value] on the RHS.
55 ///
56 /// The returned expression evaluates to the assigned value, unless
57 /// [voidContext] is true, in which case it may evaluate to anything.
58 ///
59 /// [type] is the static type of the RHS.
31 Expression buildNullAwareAssignment(Expression value, DartType type, 60 Expression buildNullAwareAssignment(Expression value, DartType type,
32 {bool voidContext: false}) { 61 {bool voidContext: false}) {
33 if (voidContext) { 62 if (voidContext) {
34 return _finish(new ConditionalExpression(buildIsNull(_makeRead()), 63 return _finish(new ConditionalExpression(buildIsNull(_makeRead()),
35 _makeWrite(value, false), new NullLiteral(), type)); 64 _makeWrite(value, false), new NullLiteral(), type));
36 } 65 }
37 var tmp = new VariableDeclaration.forValue(_makeRead()); 66 var tmp = new VariableDeclaration.forValue(_makeRead());
38 return _finish(makeLet( 67 return _finish(makeLet(
39 tmp, 68 tmp,
40 new ConditionalExpression(buildIsNull(new VariableGet(tmp)), 69 new ConditionalExpression(buildIsNull(new VariableGet(tmp)),
41 _makeWrite(value, false), new VariableGet(tmp), type))); 70 _makeWrite(value, false), new VariableGet(tmp), type)));
42 } 71 }
43 72
73 /// Returns an [Expression] representing a compound assignment (e.g. `+=`)
74 /// with the accessor on the LHS and [value] on the RHS.
44 Expression buildCompoundAssignment(Name binaryOperator, Expression value, 75 Expression buildCompoundAssignment(Name binaryOperator, Expression value,
45 {int offset: TreeNode.noOffset, 76 {int offset: TreeNode.noOffset,
46 bool voidContext: false, 77 bool voidContext: false,
47 Procedure interfaceTarget}) { 78 Procedure interfaceTarget}) {
48 return _finish(_makeWrite( 79 return _finish(_makeWrite(
49 builtBinary = makeBinary( 80 builtBinary = makeBinary(
50 _makeRead(), binaryOperator, interfaceTarget, value, 81 _makeRead(), binaryOperator, interfaceTarget, value,
51 offset: offset), 82 offset: offset),
52 voidContext)); 83 voidContext));
53 } 84 }
54 85
86 /// Returns an [Expression] representing a pre-increment or pre-decrement
87 /// of the accessor.
55 Expression buildPrefixIncrement(Name binaryOperator, 88 Expression buildPrefixIncrement(Name binaryOperator,
56 {int offset: TreeNode.noOffset, 89 {int offset: TreeNode.noOffset,
57 bool voidContext: false, 90 bool voidContext: false,
58 Procedure interfaceTarget}) { 91 Procedure interfaceTarget}) {
59 return buildCompoundAssignment(binaryOperator, new IntLiteral(1), 92 return buildCompoundAssignment(binaryOperator, new IntLiteral(1),
60 offset: offset, 93 offset: offset,
61 voidContext: voidContext, 94 voidContext: voidContext,
62 interfaceTarget: interfaceTarget); 95 interfaceTarget: interfaceTarget);
63 } 96 }
64 97
98 /// Returns an [Expression] representing a post-increment or post-decrement
99 /// of the accessor.
65 Expression buildPostfixIncrement(Name binaryOperator, 100 Expression buildPostfixIncrement(Name binaryOperator,
66 {int offset: TreeNode.noOffset, 101 {int offset: TreeNode.noOffset,
67 bool voidContext: false, 102 bool voidContext: false,
68 Procedure interfaceTarget}) { 103 Procedure interfaceTarget}) {
69 if (voidContext) { 104 if (voidContext) {
70 return buildPrefixIncrement(binaryOperator, 105 return buildPrefixIncrement(binaryOperator,
71 offset: offset, voidContext: true, interfaceTarget: interfaceTarget); 106 offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
72 } 107 }
73 var value = new VariableDeclaration.forValue(_makeRead()); 108 var value = new VariableDeclaration.forValue(_makeRead());
74 valueAccess() => new VariableGet(value); 109 valueAccess() => new VariableGet(value);
(...skipping 10 matching lines...) Expand all
85 Expression _makeSimpleWrite(Expression value, bool voidContext) { 120 Expression _makeSimpleWrite(Expression value, bool voidContext) {
86 return _makeWrite(value, voidContext); 121 return _makeWrite(value, voidContext);
87 } 122 }
88 123
89 Expression _makeRead(); 124 Expression _makeRead();
90 125
91 Expression _makeWrite(Expression value, bool voidContext); 126 Expression _makeWrite(Expression value, bool voidContext);
92 127
93 Expression _finish(Expression body) => body; 128 Expression _finish(Expression body) => body;
94 129
130 /// Returns an [Expression] representing a compile-time error.
131 ///
132 /// At runtime, an exception will be thrown.
95 makeInvalidRead() => new InvalidExpression(); 133 makeInvalidRead() => new InvalidExpression();
96 134
135 /// Returns an [Expression] representing a compile-time error wrapping
136 /// [value].
137 ///
138 /// At runtime, [value] will be evaluated before throwing an exception.
97 makeInvalidWrite(Expression value) => wrapInvalid(value); 139 makeInvalidWrite(Expression value) => wrapInvalid(value);
98 } 140 }
99 141
100 class VariableAccessor extends Accessor { 142 class VariableAccessor extends Accessor {
101 VariableDeclaration variable; 143 VariableDeclaration variable;
102 DartType promotedType; 144 DartType promotedType;
103 145
104 VariableAccessor(this.variable, [this.promotedType]); 146 VariableAccessor(this.variable, this.promotedType, int offset)
147 : super(offset);
105 148
106 _makeRead() => new VariableGet(variable, promotedType); 149 _makeRead() => new VariableGet(variable, promotedType)..fileOffset = offset;
107 150
108 _makeWrite(Expression value, bool voidContext) { 151 _makeWrite(Expression value, bool voidContext) {
109 return variable.isFinal || variable.isConst 152 return variable.isFinal || variable.isConst
110 ? makeInvalidWrite(value) 153 ? makeInvalidWrite(value)
111 : new VariableSet(variable, value); 154 : new VariableSet(variable, value)..fileOffset = offset;
112 } 155 }
113 } 156 }
114 157
115 class PropertyAccessor extends Accessor { 158 class PropertyAccessor extends Accessor {
116 VariableDeclaration _receiverVariable; 159 VariableDeclaration _receiverVariable;
117 Expression receiver; 160 Expression receiver;
118 Name name; 161 Name name;
119 Member getter, setter; 162 Member getter, setter;
120 163
121 static Accessor make( 164 static Accessor make(
122 Expression receiver, Name name, Member getter, Member setter) { 165 Expression receiver, Name name, Member getter, Member setter,
166 {int offset: TreeNode.noOffset}) {
123 if (receiver is ThisExpression) { 167 if (receiver is ThisExpression) {
124 return new ThisPropertyAccessor(name, getter, setter); 168 return new ThisPropertyAccessor(name, getter, setter, offset);
125 } else { 169 } else {
126 return new PropertyAccessor._internal(receiver, name, getter, setter); 170 return new PropertyAccessor.internal(
171 receiver, name, getter, setter, offset);
127 } 172 }
128 } 173 }
129 174
130 PropertyAccessor._internal( 175 PropertyAccessor.internal(
131 this.receiver, this.name, this.getter, this.setter); 176 this.receiver, this.name, this.getter, this.setter, int offset)
177 : super(offset);
132 178
133 _makeSimpleRead() => new PropertyGet(receiver, name, getter); 179 _makeSimpleRead() =>
180 new PropertyGet(receiver, name, getter)..fileOffset = offset;
181
134 _makeSimpleWrite(Expression value, bool voidContext) { 182 _makeSimpleWrite(Expression value, bool voidContext) {
135 return new PropertySet(receiver, name, value, setter); 183 return new PropertySet(receiver, name, value, setter)..fileOffset = offset;
136 } 184 }
137 185
138 receiverAccess() { 186 receiverAccess() {
139 _receiverVariable ??= new VariableDeclaration.forValue(receiver); 187 _receiverVariable ??= new VariableDeclaration.forValue(receiver);
140 return new VariableGet(_receiverVariable); 188 return new VariableGet(_receiverVariable)..fileOffset = offset;
141 } 189 }
142 190
143 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter); 191 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter)
192 ..fileOffset = offset;
144 193
145 _makeWrite(Expression value, bool voidContext) { 194 _makeWrite(Expression value, bool voidContext) {
146 return new PropertySet(receiverAccess(), name, value, setter); 195 return new PropertySet(receiverAccess(), name, value, setter)
196 ..fileOffset = offset;
147 } 197 }
148 198
149 _finish(Expression body) => makeLet(_receiverVariable, body); 199 _finish(Expression body) => makeLet(_receiverVariable, body);
150 } 200 }
151 201
152 /// Special case of [PropertyAccessor] to avoid creating an indirect access to 202 /// Special case of [PropertyAccessor] to avoid creating an indirect access to
153 /// 'this'. 203 /// 'this'.
154 class ThisPropertyAccessor extends Accessor { 204 class ThisPropertyAccessor extends Accessor {
155 Name name; 205 Name name;
156 Member getter, setter; 206 Member getter, setter;
157 207
158 ThisPropertyAccessor(this.name, this.getter, this.setter); 208 ThisPropertyAccessor(this.name, this.getter, this.setter, int offset)
209 : super(offset);
159 210
160 _makeRead() => 211 _makeRead() => builtGetter =
161 builtGetter = new PropertyGet(new ThisExpression(), name, getter); 212 new PropertyGet(new ThisExpression(), name, getter)..fileOffset = offset;
162 213
163 _makeWrite(Expression value, bool voidContext) { 214 _makeWrite(Expression value, bool voidContext) {
164 return new PropertySet(new ThisExpression(), name, value, setter); 215 return new PropertySet(new ThisExpression(), name, value, setter)
216 ..fileOffset = offset;
165 } 217 }
166 } 218 }
167 219
168 class NullAwarePropertyAccessor extends Accessor { 220 class NullAwarePropertyAccessor extends Accessor {
169 VariableDeclaration receiver; 221 VariableDeclaration receiver;
170 Name name; 222 Name name;
171 Member getter, setter; 223 Member getter, setter;
172 DartType type; 224 DartType type;
173 225
174 NullAwarePropertyAccessor( 226 NullAwarePropertyAccessor(Expression receiver, this.name, this.getter,
175 Expression receiver, this.name, this.getter, this.setter, this.type) 227 this.setter, this.type, int offset)
176 : this.receiver = makeOrReuseVariable(receiver); 228 : this.receiver = makeOrReuseVariable(receiver),
229 super(offset);
177 230
178 receiverAccess() => new VariableGet(receiver); 231 receiverAccess() => new VariableGet(receiver);
179 232
180 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter); 233 _makeRead() => builtGetter = new PropertyGet(receiverAccess(), name, getter);
181 234
182 _makeWrite(Expression value, bool voidContext) { 235 _makeWrite(Expression value, bool voidContext) {
183 return new PropertySet(receiverAccess(), name, value, setter); 236 return new PropertySet(receiverAccess(), name, value, setter);
184 } 237 }
185 238
186 _finish(Expression body) => makeLet( 239 _finish(Expression body) => makeLet(
187 receiver, 240 receiver,
188 new ConditionalExpression( 241 new ConditionalExpression(
189 buildIsNull(receiverAccess()), new NullLiteral(), body, type)); 242 buildIsNull(receiverAccess()), new NullLiteral(), body, type));
190 } 243 }
191 244
192 class SuperPropertyAccessor extends Accessor { 245 class SuperPropertyAccessor extends Accessor {
193 Name name; 246 Name name;
194 Member getter, setter; 247 Member getter, setter;
195 248
196 SuperPropertyAccessor(this.name, this.getter, this.setter); 249 SuperPropertyAccessor(this.name, this.getter, this.setter, int offset)
250 : super(offset);
197 251
198 _makeRead() => builtGetter = new SuperPropertyGet(name, getter); 252 _makeRead() {
253 if (getter == null) return makeInvalidRead();
254 // TODO(ahe): Use [DirectPropertyGet] when possible.
255 return builtGetter = new SuperPropertyGet(name, getter)
256 ..fileOffset = offset;
257 }
199 258
200 _makeWrite(Expression value, bool voidContext) { 259 _makeWrite(Expression value, bool voidContext) {
201 return new SuperPropertySet(name, value, setter); 260 if (setter == null) return makeInvalidWrite(value);
261 // TODO(ahe): Use [DirectPropertySet] when possible.
262 return new SuperPropertySet(name, value, setter)..fileOffset = offset;
202 } 263 }
203 } 264 }
204 265
205 final Name _indexGet = new Name('[]');
206 final Name _indexSet = new Name('[]=');
207
208 class IndexAccessor extends Accessor { 266 class IndexAccessor extends Accessor {
209 Expression receiver; 267 Expression receiver;
210 Expression index; 268 Expression index;
211 VariableDeclaration receiverVariable; 269 VariableDeclaration receiverVariable;
212 VariableDeclaration indexVariable; 270 VariableDeclaration indexVariable;
213 Procedure getter, setter; 271 Procedure getter, setter;
214 272
215 static Accessor make(Expression receiver, Expression index, Procedure getter, 273 static Accessor make(
216 Procedure setter) { 274 Expression receiver, Expression index, Procedure getter, Procedure setter,
275 {int offset: TreeNode.noOffset}) {
217 if (receiver is ThisExpression) { 276 if (receiver is ThisExpression) {
218 return new ThisIndexAccessor(index, getter, setter); 277 return new ThisIndexAccessor(index, getter, setter, offset);
219 } else { 278 } else {
220 return new IndexAccessor._internal(receiver, index, getter, setter); 279 return new IndexAccessor.internal(
280 receiver, index, getter, setter, offset);
221 } 281 }
222 } 282 }
223 283
224 IndexAccessor._internal(this.receiver, this.index, this.getter, this.setter); 284 IndexAccessor.internal(
285 this.receiver, this.index, this.getter, this.setter, int offset)
286 : super(offset);
225 287
226 _makeSimpleRead() => new MethodInvocation( 288 _makeSimpleRead() => new MethodInvocation(
227 receiver, _indexGet, new Arguments(<Expression>[index]), getter); 289 receiver, indexGetName, new Arguments(<Expression>[index]), getter)
290 ..fileOffset = offset;
228 291
229 _makeSimpleWrite(Expression value, bool voidContext) { 292 _makeSimpleWrite(Expression value, bool voidContext) {
230 if (!voidContext) return _makeWriteAndReturn(value); 293 if (!voidContext) return _makeWriteAndReturn(value);
231 return new MethodInvocation( 294 return new MethodInvocation(receiver, indexSetName,
232 receiver, _indexSet, new Arguments(<Expression>[index, value]), setter); 295 new Arguments(<Expression>[index, value]), setter)..fileOffset = offset;
233 } 296 }
234 297
235 receiverAccess() { 298 receiverAccess() {
236 // We cannot reuse the receiver if it is a variable since it might be 299 // We cannot reuse the receiver if it is a variable since it might be
237 // reassigned in the index expression. 300 // reassigned in the index expression.
238 receiverVariable ??= new VariableDeclaration.forValue(receiver); 301 receiverVariable ??= new VariableDeclaration.forValue(receiver);
239 return new VariableGet(receiverVariable); 302 return new VariableGet(receiverVariable)..fileOffset = offset;
240 } 303 }
241 304
242 indexAccess() { 305 indexAccess() {
243 indexVariable ??= new VariableDeclaration.forValue(index); 306 indexVariable ??= new VariableDeclaration.forValue(index);
244 return new VariableGet(indexVariable); 307 return new VariableGet(indexVariable)..fileOffset = offset;
245 } 308 }
246 309
247 _makeRead() { 310 _makeRead() {
248 return builtGetter = new MethodInvocation(receiverAccess(), _indexGet, 311 return builtGetter = new MethodInvocation(
249 new Arguments(<Expression>[indexAccess()]), getter); 312 receiverAccess(),
313 indexGetName,
314 new Arguments(<Expression>[indexAccess()]),
315 getter)..fileOffset = offset;
250 } 316 }
251 317
252 _makeWrite(Expression value, bool voidContext) { 318 _makeWrite(Expression value, bool voidContext) {
253 if (!voidContext) return _makeWriteAndReturn(value); 319 if (!voidContext) return _makeWriteAndReturn(value);
254 return new MethodInvocation(receiverAccess(), _indexSet, 320 return new MethodInvocation(
255 new Arguments(<Expression>[indexAccess(), value]), setter); 321 receiverAccess(),
322 indexSetName,
323 new Arguments(<Expression>[indexAccess(), value]),
324 setter)..fileOffset = offset;
256 } 325 }
257 326
258 _makeWriteAndReturn(Expression value) { 327 _makeWriteAndReturn(Expression value) {
259 // 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
260 // do. We need to bind the value in a let. 329 // do. We need to bind the value in a let.
261 var valueVariable = new VariableDeclaration.forValue(value); 330 var valueVariable = new VariableDeclaration.forValue(value);
262 var dummy = new VariableDeclaration.forValue(new MethodInvocation( 331 var dummy = new VariableDeclaration.forValue(new MethodInvocation(
263 receiverAccess(), 332 receiverAccess(),
264 _indexSet, 333 indexSetName,
265 new Arguments( 334 new Arguments(
266 <Expression>[indexAccess(), new VariableGet(valueVariable)]), 335 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
267 setter)); 336 setter)..fileOffset = offset);
268 return makeLet( 337 return makeLet(
269 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); 338 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
270 } 339 }
271 340
272 Expression _finish(Expression body) { 341 Expression _finish(Expression body) {
273 return makeLet(receiverVariable, makeLet(indexVariable, body)); 342 return makeLet(receiverVariable, makeLet(indexVariable, body));
274 } 343 }
275 } 344 }
276 345
277 /// Special case of [IndexAccessor] to avoid creating an indirect access to 346 /// Special case of [IndexAccessor] to avoid creating an indirect access to
278 /// 'this'. 347 /// 'this'.
279 class ThisIndexAccessor extends Accessor { 348 class ThisIndexAccessor extends Accessor {
280 Expression index; 349 Expression index;
281 VariableDeclaration indexVariable; 350 VariableDeclaration indexVariable;
282 Procedure getter, setter; 351 Procedure getter, setter;
283 352
284 ThisIndexAccessor(this.index, this.getter, this.setter); 353 ThisIndexAccessor(this.index, this.getter, this.setter, int offset)
354 : super(offset);
285 355
286 _makeSimpleRead() { 356 _makeSimpleRead() {
287 return new MethodInvocation(new ThisExpression(), _indexGet, 357 return new MethodInvocation(new ThisExpression(), indexGetName,
288 new Arguments(<Expression>[index]), getter); 358 new Arguments(<Expression>[index]), getter);
289 } 359 }
290 360
291 _makeSimpleWrite(Expression value, bool voidContext) { 361 _makeSimpleWrite(Expression value, bool voidContext) {
292 if (!voidContext) return _makeWriteAndReturn(value); 362 if (!voidContext) return _makeWriteAndReturn(value);
293 return new MethodInvocation(new ThisExpression(), _indexSet, 363 return new MethodInvocation(new ThisExpression(), indexSetName,
294 new Arguments(<Expression>[index, value]), setter); 364 new Arguments(<Expression>[index, value]), setter);
295 } 365 }
296 366
297 indexAccess() { 367 indexAccess() {
298 indexVariable ??= new VariableDeclaration.forValue(index); 368 indexVariable ??= new VariableDeclaration.forValue(index);
299 return new VariableGet(indexVariable); 369 return new VariableGet(indexVariable);
300 } 370 }
301 371
302 _makeRead() => builtGetter = new MethodInvocation(new ThisExpression(), 372 _makeRead() => builtGetter = new MethodInvocation(new ThisExpression(),
303 _indexGet, new Arguments(<Expression>[indexAccess()]), getter); 373 indexGetName, new Arguments(<Expression>[indexAccess()]), getter);
304 374
305 _makeWrite(Expression value, bool voidContext) { 375 _makeWrite(Expression value, bool voidContext) {
306 if (!voidContext) return _makeWriteAndReturn(value); 376 if (!voidContext) return _makeWriteAndReturn(value);
307 return new MethodInvocation(new ThisExpression(), _indexSet, 377 return new MethodInvocation(new ThisExpression(), indexSetName,
308 new Arguments(<Expression>[indexAccess(), value]), setter); 378 new Arguments(<Expression>[indexAccess(), value]), setter);
309 } 379 }
310 380
311 _makeWriteAndReturn(Expression value) { 381 _makeWriteAndReturn(Expression value) {
312 var valueVariable = new VariableDeclaration.forValue(value); 382 var valueVariable = new VariableDeclaration.forValue(value);
313 var dummy = new VariableDeclaration.forValue(new MethodInvocation( 383 var dummy = new VariableDeclaration.forValue(new MethodInvocation(
314 new ThisExpression(), 384 new ThisExpression(),
315 _indexSet, 385 indexSetName,
316 new Arguments( 386 new Arguments(
317 <Expression>[indexAccess(), new VariableGet(valueVariable)]), 387 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
318 setter)); 388 setter));
319 return makeLet( 389 return makeLet(
320 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); 390 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
321 } 391 }
322 392
323 Expression _finish(Expression body) => makeLet(indexVariable, body); 393 Expression _finish(Expression body) => makeLet(indexVariable, body);
324 } 394 }
325 395
326 class SuperIndexAccessor extends Accessor { 396 class SuperIndexAccessor extends Accessor {
327 Expression index; 397 Expression index;
328 VariableDeclaration indexVariable; 398 VariableDeclaration indexVariable;
329 Member getter, setter; 399 Member getter, setter;
330 400
331 SuperIndexAccessor(this.index, this.getter, this.setter); 401 SuperIndexAccessor(this.index, this.getter, this.setter, int offset)
402 : super(offset);
332 403
333 indexAccess() { 404 indexAccess() {
334 indexVariable ??= new VariableDeclaration.forValue(index); 405 indexVariable ??= new VariableDeclaration.forValue(index);
335 return new VariableGet(indexVariable); 406 return new VariableGet(indexVariable);
336 } 407 }
337 408
338 _makeSimpleRead() => new SuperMethodInvocation( 409 _makeSimpleRead() => new SuperMethodInvocation(
339 _indexGet, new Arguments(<Expression>[index]), getter); 410 indexGetName, new Arguments(<Expression>[index]), getter);
340 411
341 _makeSimpleWrite(Expression value, bool voidContext) { 412 _makeSimpleWrite(Expression value, bool voidContext) {
342 if (!voidContext) return _makeWriteAndReturn(value); 413 if (!voidContext) return _makeWriteAndReturn(value);
343 return new SuperMethodInvocation( 414 return new SuperMethodInvocation(
344 _indexSet, new Arguments(<Expression>[index, value]), setter); 415 indexSetName, new Arguments(<Expression>[index, value]), setter);
345 } 416 }
346 417
347 _makeRead() { 418 _makeRead() {
348 return builtGetter = new SuperMethodInvocation( 419 return builtGetter = new SuperMethodInvocation(
349 _indexGet, new Arguments(<Expression>[indexAccess()]), getter); 420 indexGetName, new Arguments(<Expression>[indexAccess()]), getter);
350 } 421 }
351 422
352 _makeWrite(Expression value, bool voidContext) { 423 _makeWrite(Expression value, bool voidContext) {
353 if (!voidContext) return _makeWriteAndReturn(value); 424 if (!voidContext) return _makeWriteAndReturn(value);
354 return new SuperMethodInvocation( 425 return new SuperMethodInvocation(indexSetName,
355 _indexSet, new Arguments(<Expression>[indexAccess(), value]), setter); 426 new Arguments(<Expression>[indexAccess(), value]), setter);
356 } 427 }
357 428
358 _makeWriteAndReturn(Expression value) { 429 _makeWriteAndReturn(Expression value) {
359 var valueVariable = new VariableDeclaration.forValue(value); 430 var valueVariable = new VariableDeclaration.forValue(value);
360 var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation( 431 var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation(
361 _indexSet, 432 indexSetName,
362 new Arguments( 433 new Arguments(
363 <Expression>[indexAccess(), new VariableGet(valueVariable)]), 434 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
364 setter)); 435 setter));
365 return makeLet( 436 return makeLet(
366 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); 437 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
367 } 438 }
368 439
369 Expression _finish(Expression body) { 440 Expression _finish(Expression body) {
370 return makeLet(indexVariable, body); 441 return makeLet(indexVariable, body);
371 } 442 }
372 } 443 }
373 444
374 class StaticAccessor extends Accessor { 445 class StaticAccessor extends Accessor {
375 Member readTarget; 446 Member readTarget;
376 Member writeTarget; 447 Member writeTarget;
377 448
378 StaticAccessor(this.readTarget, this.writeTarget); 449 StaticAccessor(this.readTarget, this.writeTarget, int offset) : super(offset);
379 450
380 _makeRead() => builtGetter = 451 _makeRead() => builtGetter = readTarget == null
381 readTarget == null ? makeInvalidRead() : new StaticGet(readTarget); 452 ? makeInvalidRead()
453 : new StaticGet(readTarget)..fileOffset = offset;
382 454
383 _makeWrite(Expression value, bool voidContext) { 455 _makeWrite(Expression value, bool voidContext) {
384 return writeTarget == null 456 return writeTarget == null
385 ? makeInvalidWrite(value) 457 ? makeInvalidWrite(value)
386 : new StaticSet(writeTarget, value); 458 : new StaticSet(writeTarget, value)..fileOffset = offset;
387 } 459 }
388 } 460 }
389 461
390 class ReadOnlyAccessor extends Accessor { 462 class ReadOnlyAccessor extends Accessor {
391 Expression expression; 463 Expression expression;
392 VariableDeclaration value; 464 VariableDeclaration value;
393 465
394 ReadOnlyAccessor(this.expression); 466 ReadOnlyAccessor(this.expression, int offset) : super(offset);
395 467
396 _makeSimpleRead() => expression; 468 _makeSimpleRead() => expression;
397 469
398 _makeRead() { 470 _makeRead() {
399 value ??= new VariableDeclaration.forValue(expression); 471 value ??= new VariableDeclaration.forValue(expression);
400 return new VariableGet(value); 472 return new VariableGet(value);
401 } 473 }
402 474
403 _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value); 475 _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value);
404 476
(...skipping 22 matching lines...) Expand all
427 499
428 VariableDeclaration makeOrReuseVariable(Expression value) { 500 VariableDeclaration makeOrReuseVariable(Expression value) {
429 // TODO: Devise a way to remember if a variable declaration was reused 501 // TODO: Devise a way to remember if a variable declaration was reused
430 // or is fresh (hence needs a let binding). 502 // or is fresh (hence needs a let binding).
431 return new VariableDeclaration.forValue(value); 503 return new VariableDeclaration.forValue(value);
432 } 504 }
433 505
434 Expression wrapInvalid(Expression e) { 506 Expression wrapInvalid(Expression e) {
435 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); 507 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression());
436 } 508 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698