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

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

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

Powered by Google App Engine
This is Rietveld 408576698