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

Side by Side Diff: pkg/fasta/lib/src/kernel/frontend_accessors.dart

Issue 2628043005: Fasta kernel AST builder. (Closed)
Patch Set: Rebased. Created 3 years, 11 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 // Note: copied from package:kernel at revision 7346348.
6
7 /// A library to help transform compounds and null-aware accessors into
8 /// let expressions.
9 library kernel.frontend.accessors;
10
11 import 'package:kernel/ast.dart';
12
13 abstract class Accessor {
14 Expression buildSimpleRead() {
15 return _finish(_makeSimpleRead());
16 }
17
18 /// Returns an assignment to the accessor.
19 ///
20 /// The returned expression evaluates to the assigned value, unless
21 /// [voidContext] is true, in which case it may evaluate to anything.
22 Expression buildAssignment(Expression value, {bool voidContext: false}) {
23 return _finish(_makeSimpleWrite(value, voidContext));
24 }
25
26 Expression buildNullAwareAssignment(Expression value, DartType type,
27 {bool voidContext: false}) {
28 if (voidContext) {
29 return _finish(new ConditionalExpression(buildIsNull(_makeRead()),
30 _makeWrite(value, voidContext), new NullLiteral(), type));
31 }
32 var tmp = new VariableDeclaration.forValue(_makeRead());
33 return _finish(makeLet(
34 tmp,
35 new ConditionalExpression(buildIsNull(new VariableGet(tmp)),
36 _makeWrite(value, voidContext), new VariableGet(tmp), type)));
37 }
38
39 Expression buildCompoundAssignment(Name binaryOperator, Expression value,
40 {bool voidContext: false, Procedure interfaceTarget}) {
41 return _finish(_makeWrite(
42 makeBinary(_makeRead(), binaryOperator, interfaceTarget, value),
43 voidContext));
44 }
45
46 Expression buildPrefixIncrement(Name binaryOperator,
47 {bool voidContext: false, Procedure interfaceTarget}) {
48 return buildCompoundAssignment(binaryOperator, new IntLiteral(1),
49 voidContext: voidContext, interfaceTarget: interfaceTarget);
50 }
51
52 Expression buildPostfixIncrement(Name binaryOperator,
53 {bool voidContext: false, Procedure interfaceTarget}) {
54 if (voidContext) {
55 return buildPrefixIncrement(binaryOperator,
56 voidContext: true, interfaceTarget: interfaceTarget);
57 }
58 var value = new VariableDeclaration.forValue(_makeRead());
59 valueAccess() => new VariableGet(value);
60 var dummy = new VariableDeclaration.forValue(_makeWrite(
61 makeBinary(
62 valueAccess(), binaryOperator, interfaceTarget, new IntLiteral(1)),
63 true));
64 return _finish(makeLet(value, makeLet(dummy, valueAccess())));
65 }
66
67 Expression _makeSimpleRead() => _makeRead();
68
69 Expression _makeSimpleWrite(Expression value, bool voidContext) {
70 return _makeWrite(value, voidContext);
71 }
72
73 Expression _makeRead();
74
75 Expression _makeWrite(Expression value, bool voidContext);
76
77 Expression _finish(Expression body) => body;
78
79 makeInvalidRead() => new InvalidExpression();
80
81 makeInvalidWrite(Expression value) => wrapInvalid(value);
82 }
83
84 class VariableAccessor extends Accessor {
85 VariableDeclaration variable;
86 DartType promotedType;
87
88 VariableAccessor(this.variable, [this.promotedType]);
89
90 VariableAccessor.internal(this.variable, this.promotedType);
91
92 _makeRead() => new VariableGet(variable, promotedType);
93
94 _makeWrite(Expression value, bool voidContext) {
95 return variable.isFinal || variable.isConst
96 ? makeInvalidWrite(value)
97 : new VariableSet(variable, value);
98 }
99 }
100
101 class PropertyAccessor extends Accessor {
102 VariableDeclaration _receiverVariable;
103 Expression receiver;
104 Name name;
105 Member getter, setter;
106
107 static Accessor make(
108 Expression receiver, Name name, Member getter, Member setter) {
109 if (receiver is ThisExpression) {
110 return new ThisPropertyAccessor(name, getter, setter);
111 } else {
112 return new PropertyAccessor.internal(receiver, name, getter, setter);
113 }
114 }
115
116 PropertyAccessor.internal(
117 this.receiver, this.name, this.getter, this.setter);
118
119 _makeSimpleRead() => new PropertyGet(receiver, name, getter);
120 _makeSimpleWrite(Expression value, bool voidContext) {
121 return new PropertySet(receiver, name, value, setter);
122 }
123
124 receiverAccess() {
125 _receiverVariable ??= new VariableDeclaration.forValue(receiver);
126 return new VariableGet(_receiverVariable);
127 }
128
129 _makeRead() => new PropertyGet(receiverAccess(), name, getter);
130
131 _makeWrite(Expression value, bool voidContext) {
132 return new PropertySet(receiverAccess(), name, value, setter);
133 }
134
135 _finish(Expression body) => makeLet(_receiverVariable, body);
136 }
137
138 /// Special case of [PropertyAccessor] to avoid creating an indirect access to
139 /// 'this'.
140 class ThisPropertyAccessor extends Accessor {
141 Name name;
142 Member getter, setter;
143
144 ThisPropertyAccessor(this.name, this.getter, this.setter);
145
146 _makeRead() => new PropertyGet(new ThisExpression(), name, getter);
147
148 _makeWrite(Expression value, bool voidContext) {
149 return new PropertySet(new ThisExpression(), name, value, setter);
150 }
151 }
152
153 class NullAwarePropertyAccessor extends Accessor {
154 VariableDeclaration receiver;
155 Name name;
156 Member getter, setter;
157 DartType type;
158
159 NullAwarePropertyAccessor(
160 Expression receiver, this.name, this.getter, this.setter, this.type)
161 : this.receiver = makeOrReuseVariable(receiver);
162
163 receiverAccess() => new VariableGet(receiver);
164
165 _makeRead() => new PropertyGet(receiverAccess(), name, getter);
166
167 _makeWrite(Expression value, bool voidContext) {
168 return new PropertySet(receiverAccess(), name, value, setter);
169 }
170
171 _finish(Expression body) => makeLet(
172 receiver,
173 new ConditionalExpression(
174 buildIsNull(receiverAccess()), new NullLiteral(), body, type));
175 }
176
177 class SuperPropertyAccessor extends Accessor {
178 Name name;
179 Member getter, setter;
180
181 SuperPropertyAccessor(this.name, this.getter, this.setter);
182
183 _makeRead() {
184 if (getter == null) return makeInvalidRead();
185 // TODO(ahe): Use [DirectPropertyGet] when possible.
186 Expression result = new DirectPropertyGet(new ThisExpression(), getter);
187 result = new SuperPropertyGet(name, getter);
188 return result;
189 }
190
191 _makeWrite(Expression value, bool voidContext) {
192 if (setter == null) return makeInvalidWrite(value);
193 // TODO(ahe): Use [DirectPropertySet] when possible.
194 Expression result =
195 new DirectPropertySet(new ThisExpression(), setter, value);
196 result = new SuperPropertySet(name, value, setter);
197 return result;
198 }
199 }
200
201 final Name _indexGet = new Name('[]');
202 final Name _indexSet = new Name('[]=');
203
204 class IndexAccessor extends Accessor {
205 Expression receiver;
206 Expression index;
207 VariableDeclaration receiverVariable;
208 VariableDeclaration indexVariable;
209 Procedure getter, setter;
210
211 static Accessor make(Expression receiver, Expression index, Procedure getter,
212 Procedure setter) {
213 if (receiver is ThisExpression) {
214 return new ThisIndexAccessor(index, getter, setter);
215 } else {
216 return new IndexAccessor.internal(receiver, index, getter, setter);
217 }
218 }
219
220 IndexAccessor.internal(this.receiver, this.index, this.getter, this.setter);
221
222 _makeSimpleRead() => new MethodInvocation(
223 receiver, _indexGet, new Arguments(<Expression>[index]), getter);
224
225 _makeSimpleWrite(Expression value, bool voidContext) {
226 if (!voidContext) return _makeWriteAndReturn(value);
227 return new MethodInvocation(
228 receiver, _indexSet, new Arguments(<Expression>[index, value]), setter);
229 }
230
231 receiverAccess() {
232 // We cannot reuse the receiver if it is a variable since it might be
233 // reassigned in the index expression.
234 receiverVariable ??= new VariableDeclaration.forValue(receiver);
235 return new VariableGet(receiverVariable);
236 }
237
238 indexAccess() {
239 indexVariable ??= new VariableDeclaration.forValue(index);
240 return new VariableGet(indexVariable);
241 }
242
243 _makeRead() {
244 return new MethodInvocation(receiverAccess(), _indexGet,
245 new Arguments(<Expression>[indexAccess()]), getter);
246 }
247
248 _makeWrite(Expression value, bool voidContext) {
249 if (!voidContext) return _makeWriteAndReturn(value);
250 return new MethodInvocation(receiverAccess(), _indexSet,
251 new Arguments(<Expression>[indexAccess(), value]), setter);
252 }
253
254 _makeWriteAndReturn(Expression value) {
255 // The call to []= does not return the value like direct-style assignments
256 // do. We need to bind the value in a let.
257 var valueVariable = new VariableDeclaration.forValue(value);
258 var dummy = new VariableDeclaration.forValue(new MethodInvocation(
259 receiverAccess(),
260 _indexSet,
261 new Arguments(
262 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
263 setter));
264 return makeLet(
265 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
266 }
267
268 Expression _finish(Expression body) {
269 return makeLet(receiverVariable, makeLet(indexVariable, body));
270 }
271 }
272
273 /// Special case of [IndexAccessor] to avoid creating an indirect access to
274 /// 'this'.
275 class ThisIndexAccessor extends Accessor {
276 Expression index;
277 VariableDeclaration indexVariable;
278 Procedure getter, setter;
279
280 ThisIndexAccessor(this.index, this.getter, this.setter);
281
282 _makeSimpleRead() {
283 return new MethodInvocation(new ThisExpression(), _indexGet,
284 new Arguments(<Expression>[index]), getter);
285 }
286
287 _makeSimpleWrite(Expression value, bool voidContext) {
288 if (!voidContext) return _makeWriteAndReturn(value);
289 return new MethodInvocation(new ThisExpression(), _indexSet,
290 new Arguments(<Expression>[index, value]), setter);
291 }
292
293 indexAccess() {
294 indexVariable ??= new VariableDeclaration.forValue(index);
295 return new VariableGet(indexVariable);
296 }
297
298 _makeRead() => new MethodInvocation(new ThisExpression(), _indexGet,
299 new Arguments(<Expression>[indexAccess()]), getter);
300
301 _makeWrite(Expression value, bool voidContext) {
302 if (!voidContext) return _makeWriteAndReturn(value);
303 return new MethodInvocation(new ThisExpression(), _indexSet,
304 new Arguments(<Expression>[indexAccess(), value]), setter);
305 }
306
307 _makeWriteAndReturn(Expression value) {
308 var valueVariable = new VariableDeclaration.forValue(value);
309 var dummy = new VariableDeclaration.forValue(new MethodInvocation(
310 new ThisExpression(),
311 _indexSet,
312 new Arguments(
313 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
314 setter));
315 return makeLet(
316 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
317 }
318
319 Expression _finish(Expression body) => makeLet(indexVariable, body);
320 }
321
322 class SuperIndexAccessor extends Accessor {
323 Expression index;
324 VariableDeclaration indexVariable;
325 Member getter, setter;
326
327 SuperIndexAccessor(this.index, this.getter, this.setter);
328
329 indexAccess() {
330 indexVariable ??= new VariableDeclaration.forValue(index);
331 return new VariableGet(indexVariable);
332 }
333
334 _makeSimpleRead() => new SuperMethodInvocation(
335 _indexGet, new Arguments(<Expression>[index]), getter);
336
337 _makeSimpleWrite(Expression value, bool voidContext) {
338 if (!voidContext) return _makeWriteAndReturn(value);
339 return new SuperMethodInvocation(
340 _indexSet, new Arguments(<Expression>[index, value]), setter);
341 }
342
343 _makeRead() {
344 return new SuperMethodInvocation(
345 _indexGet, new Arguments(<Expression>[indexAccess()]), getter);
346 }
347
348 _makeWrite(Expression value, bool voidContext) {
349 if (!voidContext) return _makeWriteAndReturn(value);
350 return new SuperMethodInvocation(
351 _indexSet, new Arguments(<Expression>[indexAccess(), value]), setter);
352 }
353
354 _makeWriteAndReturn(Expression value) {
355 var valueVariable = new VariableDeclaration.forValue(value);
356 var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation(
357 _indexSet,
358 new Arguments(
359 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
360 setter));
361 return makeLet(
362 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
363 }
364
365 Expression _finish(Expression body) {
366 return makeLet(indexVariable, body);
367 }
368 }
369
370 class StaticAccessor extends Accessor {
371 Member readTarget;
372 Member writeTarget;
373
374 StaticAccessor(this.readTarget, this.writeTarget);
375
376 _makeRead() =>
377 readTarget == null ? makeInvalidRead() : new StaticGet(readTarget);
378
379 _makeWrite(Expression value, bool voidContext) {
380 return writeTarget == null
381 ? makeInvalidWrite(value)
382 : new StaticSet(writeTarget, value);
383 }
384 }
385
386 class ReadOnlyAccessor extends Accessor {
387 Expression expression;
388 VariableDeclaration value;
389
390 ReadOnlyAccessor(this.expression);
391
392 _makeSimpleRead() => expression;
393
394 _makeRead() {
395 value ??= new VariableDeclaration.forValue(expression);
396 return new VariableGet(value);
397 }
398
399 _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value);
400
401 Expression _finish(Expression body) => makeLet(value, body);
402 }
403
404 Expression makeLet(VariableDeclaration variable, Expression body) {
405 if (variable == null) return body;
406 return new Let(variable, body);
407 }
408
409 Expression makeBinary(Expression left, Name operator, Procedure interfaceTarget,
410 Expression right) {
411 return new MethodInvocation(
412 left, operator, new Arguments(<Expression>[right]), interfaceTarget);
413 }
414
415 final Name _equalOperator = new Name('==');
416
417 Expression buildIsNull(Expression value) {
418 return makeBinary(value, _equalOperator, null, new NullLiteral());
419 }
420
421 VariableDeclaration makeOrReuseVariable(Expression value) {
422 // TODO: Devise a way to remember if a variable declaration was reused
423 // or is fresh (hence needs a let binding).
424 return new VariableDeclaration.forValue(value);
425 }
426
427 Expression wrapInvalid(Expression e) {
428 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression());
429 }
OLDNEW
« no previous file with comments | « pkg/fasta/lib/src/kernel/builder_accessors.dart ('k') | pkg/fasta/lib/src/kernel/redirecting_factory_body.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698