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

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

Issue 2768533002: Fasta type inference prototype #2
Patch Set: Rework atop 415c868589d02e98eb839f48150f4203d5cecdb0 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 // Note: copied from package:kernel at revision 7346348. 5 // Note: copied from package:kernel at revision 7346348.
6 6
7 /// A library to help transform compounds and null-aware accessors into 7 /// A library to help transform compounds and null-aware accessors into
8 /// let expressions. 8 /// let expressions.
9 library kernel.frontend.accessors; 9 library kernel.frontend.accessors;
10 10
11 import 'package:front_end/src/fasta/builder/shadow_ast.dart';
12 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
11 import 'package:kernel/ast.dart'; 13 import 'package:kernel/ast.dart';
12 14
13 import '../names.dart' show indexGetName, indexSetName; 15 import '../names.dart' show indexGetName, indexSetName;
14 16
15 /// An [Accessor] represents a subexpression for which we can't yet build a 17 /// 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 18 /// kernel [Expression] because we don't yet know the context in which it is
17 /// used. 19 /// used.
18 /// 20 ///
19 /// Once the context is known, an [Accessor] can be converted into an 21 /// Once the context is known, an [Accessor] can be converted into an
20 /// [Expression] by calling a "build" method. 22 /// [Expression] by calling a "build" method.
21 /// 23 ///
22 /// For example, when building a kernel representation for `a[x] = b`, after 24 /// 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 25 /// 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 26 /// generate an invocation of `operator[]` or `operator[]=`, so we generate an
25 /// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be 27 /// [Accessor] object. Later, after `= b` is parsed, [buildAssignment] will be
26 /// called. 28 /// called.
27 abstract class Accessor { 29 abstract class Accessor {
28 /// Builds an [Expression] representing a read from the accessor. 30 /// Builds an [Expression] representing a read from the accessor.
29 Expression buildSimpleRead() { 31 ShadowExpression buildSimpleRead() {
30 return _finish(_makeSimpleRead()); 32 return _finish(_makeSimpleRead() as ShadowExpression);
31 } 33 }
32 34
33 /// Builds an [Expression] representing an assignment with the accessor on 35 /// Builds an [Expression] representing an assignment with the accessor on
34 /// the LHS and [value] on the RHS. 36 /// the LHS and [value] on the RHS.
35 /// 37 ///
36 /// The returned expression evaluates to the assigned value, unless 38 /// The returned expression evaluates to the assigned value, unless
37 /// [voidContext] is true, in which case it may evaluate to anything. 39 /// [voidContext] is true, in which case it may evaluate to anything.
38 Expression buildAssignment(Expression value, {bool voidContext: false}) { 40 Expression buildAssignment(Expression value, {bool voidContext: false}) {
39 return _finish(_makeSimpleWrite(value, voidContext)); 41 return _finish(_makeSimpleWrite(value, voidContext) as ShadowExpression)
42 as Expression;
40 } 43 }
41 44
42 /// Returns an [Expression] representing a null-aware assignment (`??=`) with 45 /// Returns an [Expression] representing a null-aware assignment (`??=`) with
43 /// the accessor on the LHS and [value] on the RHS. 46 /// the accessor on the LHS and [value] on the RHS.
44 /// 47 ///
45 /// The returned expression evaluates to the assigned value, unless 48 /// The returned expression evaluates to the assigned value, unless
46 /// [voidContext] is true, in which case it may evaluate to anything. 49 /// [voidContext] is true, in which case it may evaluate to anything.
47 /// 50 ///
48 /// [type] is the static type of the RHS. 51 /// [type] is the static type of the RHS.
49 Expression buildNullAwareAssignment(Expression value, DartType type, 52 Expression buildNullAwareAssignment(Expression value, DartType type,
50 {bool voidContext: false}) { 53 {bool voidContext: false}) {
51 if (voidContext) { 54 if (voidContext) {
52 return _finish(new ConditionalExpression(buildIsNull(_makeRead()), 55 return _finish(new ConditionalExpression(
53 _makeWrite(value, false), new NullLiteral(), type)); 56 buildIsNull(_makeRead()),
57 _makeWrite(value, false),
58 new NullLiteral(),
59 type) as ShadowExpression) as Expression;
54 } 60 }
55 var tmp = new VariableDeclaration.forValue(_makeRead()); 61 var tmp = new VariableDeclaration.forValue(_makeRead());
56 return _finish(makeLet( 62 return _finish(makeLet(
57 tmp, 63 tmp,
58 new ConditionalExpression(buildIsNull(new VariableGet(tmp)), 64 new ConditionalExpression(
59 _makeWrite(value, false), new VariableGet(tmp), type))); 65 buildIsNull(new VariableGet(tmp)),
66 _makeWrite(value, false),
67 new VariableGet(tmp),
68 type)) as ShadowExpression) as Expression;
60 } 69 }
61 70
62 /// Returns an [Expression] representing a compound assignment (e.g. `+=`) 71 /// Returns an [Expression] representing a compound assignment (e.g. `+=`)
63 /// with the accessor on the LHS and [value] on the RHS. 72 /// with the accessor on the LHS and [value] on the RHS.
64 Expression buildCompoundAssignment( 73 Expression buildCompoundAssignment(
65 Name binaryOperator, Expression value, int charOffset, 74 Name binaryOperator, Expression value, int charOffset,
66 {bool voidContext: false, Procedure interfaceTarget}) { 75 {bool voidContext: false, Procedure interfaceTarget}) {
67 return _finish(_makeWrite( 76 return _finish(_makeWrite(
68 makeBinary( 77 makeBinary(
69 _makeRead(), binaryOperator, interfaceTarget, value, charOffset), 78 _makeRead(), binaryOperator, interfaceTarget, value, charOffset),
70 voidContext)); 79 voidContext) as ShadowExpression) as Expression;
71 } 80 }
72 81
73 /// Returns an [Expression] representing a pre-increment or pre-decrement 82 /// Returns an [Expression] representing a pre-increment or pre-decrement
74 /// of the accessor. 83 /// of the accessor.
75 Expression buildPrefixIncrement(Name binaryOperator, int charOffset, 84 Expression buildPrefixIncrement(Name binaryOperator, int charOffset,
76 {bool voidContext: false, Procedure interfaceTarget}) { 85 {bool voidContext: false, Procedure interfaceTarget}) {
77 return buildCompoundAssignment( 86 return buildCompoundAssignment(
78 binaryOperator, new IntLiteral(1), charOffset, 87 binaryOperator, new IntLiteral(1), charOffset,
79 voidContext: voidContext, interfaceTarget: interfaceTarget); 88 voidContext: voidContext, interfaceTarget: interfaceTarget);
80 } 89 }
81 90
82 /// Returns an [Expression] representing a post-increment or post-decrement 91 /// Returns an [Expression] representing a post-increment or post-decrement
83 /// of the accessor. 92 /// of the accessor.
84 Expression buildPostfixIncrement(Name binaryOperator, int charOffset, 93 Expression buildPostfixIncrement(Name binaryOperator, int charOffset,
85 {bool voidContext: false, Procedure interfaceTarget}) { 94 {bool voidContext: false, Procedure interfaceTarget}) {
86 if (voidContext) { 95 if (voidContext) {
87 return buildPrefixIncrement(binaryOperator, charOffset, 96 return buildPrefixIncrement(binaryOperator, charOffset,
88 voidContext: true, interfaceTarget: interfaceTarget); 97 voidContext: true, interfaceTarget: interfaceTarget);
89 } 98 }
90 var value = new VariableDeclaration.forValue(_makeRead()); 99 var value = new VariableDeclaration.forValue(_makeRead());
91 valueAccess() => new VariableGet(value); 100 valueAccess() => new VariableGet(value);
92 var dummy = new VariableDeclaration.forValue(_makeWrite( 101 var dummy = new VariableDeclaration.forValue(_makeWrite(
93 makeBinary(valueAccess(), binaryOperator, interfaceTarget, 102 makeBinary(valueAccess(), binaryOperator, interfaceTarget,
94 new IntLiteral(1), charOffset), 103 new IntLiteral(1), charOffset),
95 true)); 104 true));
96 return _finish(makeLet(value, makeLet(dummy, valueAccess()))); 105 return _finish(
106 makeLet(value, makeLet(dummy, valueAccess())) as ShadowExpression)
107 as Expression;
97 } 108 }
98 109
99 Expression _makeSimpleRead() => _makeRead(); 110 Expression _makeSimpleRead() => _makeRead();
100 111
101 Expression _makeSimpleWrite(Expression value, bool voidContext) { 112 Expression _makeSimpleWrite(Expression value, bool voidContext) {
102 return _makeWrite(value, voidContext); 113 return _makeWrite(value, voidContext);
103 } 114 }
104 115
105 Expression _makeRead(); 116 Expression _makeRead();
106 117
107 Expression _makeWrite(Expression value, bool voidContext); 118 Expression _makeWrite(Expression value, bool voidContext);
108 119
109 Expression _finish(Expression body) => body; 120 ShadowExpression _finish(ShadowExpression body) => body;
110 121
111 /// Returns an [Expression] representing a compile-time error. 122 /// Returns an [Expression] representing a compile-time error.
112 /// 123 ///
113 /// At runtime, an exception will be thrown. 124 /// At runtime, an exception will be thrown.
114 makeInvalidRead() => new InvalidExpression(); 125 makeInvalidRead() => new InvalidExpression();
115 126
116 /// Returns an [Expression] representing a compile-time error wrapping 127 /// Returns an [Expression] representing a compile-time error wrapping
117 /// [value]. 128 /// [value].
118 /// 129 ///
119 /// At runtime, [value] will be evaluated before throwing an exception. 130 /// At runtime, [value] will be evaluated before throwing an exception.
120 makeInvalidWrite(Expression value) => wrapInvalid(value); 131 makeInvalidWrite(Expression value) => wrapInvalid(value);
121 } 132 }
122 133
123 class VariableAccessor extends Accessor { 134 class VariableAccessor extends Accessor {
124 VariableDeclaration variable; 135 VariableDeclaration variable;
125 int charOffset; 136 int charOffset;
126 DartType promotedType; 137 DartType promotedType;
127 138
128 VariableAccessor(this.variable, [this.promotedType]); 139 VariableAccessor(this.variable, [this.promotedType]);
129 140
130 VariableAccessor.internal(this.variable, this.charOffset, this.promotedType); 141 VariableAccessor.internal(this.variable, this.charOffset, this.promotedType);
131 142
132 _makeRead() => 143 _makeRead() =>
133 new VariableGet(variable, promotedType)..fileOffset = charOffset; 144 new KernelVariableGet(variable, promotedType)..fileOffset = charOffset;
134 145
135 _makeWrite(Expression value, bool voidContext) { 146 _makeWrite(Expression value, bool voidContext) {
136 return variable.isFinal || variable.isConst 147 return variable.isFinal || variable.isConst
137 ? makeInvalidWrite(value) 148 ? makeInvalidWrite(value)
138 : new VariableSet(variable, value)..fileOffset = charOffset; 149 : new VariableSet(variable, value)..fileOffset = charOffset;
139 } 150 }
140 } 151 }
141 152
142 class PropertyAccessor extends Accessor { 153 class PropertyAccessor extends Accessor {
143 VariableDeclaration _receiverVariable; 154 VariableDeclaration _receiverVariable;
(...skipping 28 matching lines...) Expand all
172 } 183 }
173 184
174 _makeRead() => 185 _makeRead() =>
175 new PropertyGet(receiverAccess(), name, getter)..fileOffset = charOffset; 186 new PropertyGet(receiverAccess(), name, getter)..fileOffset = charOffset;
176 187
177 _makeWrite(Expression value, bool voidContext) { 188 _makeWrite(Expression value, bool voidContext) {
178 return new PropertySet(receiverAccess(), name, value, setter) 189 return new PropertySet(receiverAccess(), name, value, setter)
179 ..fileOffset = charOffset; 190 ..fileOffset = charOffset;
180 } 191 }
181 192
182 _finish(Expression body) => makeLet(_receiverVariable, body); 193 _finish(ShadowExpression body) =>
194 makeLet(_receiverVariable, body as Expression) as ShadowExpression;
183 } 195 }
184 196
185 /// Special case of [PropertyAccessor] to avoid creating an indirect access to 197 /// Special case of [PropertyAccessor] to avoid creating an indirect access to
186 /// 'this'. 198 /// 'this'.
187 class ThisPropertyAccessor extends Accessor { 199 class ThisPropertyAccessor extends Accessor {
188 Name name; 200 Name name;
189 Member getter, setter; 201 Member getter, setter;
190 final int charOffset; 202 final int charOffset;
191 203
192 ThisPropertyAccessor(this.name, this.getter, this.setter, this.charOffset); 204 ThisPropertyAccessor(this.name, this.getter, this.setter, this.charOffset);
(...skipping 18 matching lines...) Expand all
211 : this.receiver = makeOrReuseVariable(receiver); 223 : this.receiver = makeOrReuseVariable(receiver);
212 224
213 receiverAccess() => new VariableGet(receiver); 225 receiverAccess() => new VariableGet(receiver);
214 226
215 _makeRead() => new PropertyGet(receiverAccess(), name, getter); 227 _makeRead() => new PropertyGet(receiverAccess(), name, getter);
216 228
217 _makeWrite(Expression value, bool voidContext) { 229 _makeWrite(Expression value, bool voidContext) {
218 return new PropertySet(receiverAccess(), name, value, setter); 230 return new PropertySet(receiverAccess(), name, value, setter);
219 } 231 }
220 232
221 _finish(Expression body) => makeLet( 233 _finish(ShadowExpression body) => makeLet(
222 receiver, 234 receiver,
223 new ConditionalExpression( 235 new ConditionalExpression(buildIsNull(receiverAccess()),
224 buildIsNull(receiverAccess()), new NullLiteral(), body, type)); 236 new NullLiteral(), body as Expression, type)) as ShadowExpression;
225 } 237 }
226 238
227 class SuperPropertyAccessor extends Accessor { 239 class SuperPropertyAccessor extends Accessor {
228 Name name; 240 Name name;
229 Member getter, setter; 241 Member getter, setter;
230 final int charOffset; 242 final int charOffset;
231 243
232 SuperPropertyAccessor(this.name, this.getter, this.setter, this.charOffset); 244 SuperPropertyAccessor(this.name, this.getter, this.setter, this.charOffset);
233 245
234 _makeRead() { 246 _makeRead() {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 var dummy = new VariableDeclaration.forValue(new MethodInvocation( 332 var dummy = new VariableDeclaration.forValue(new MethodInvocation(
321 receiverAccess(), 333 receiverAccess(),
322 indexSetName, 334 indexSetName,
323 new Arguments( 335 new Arguments(
324 <Expression>[indexAccess(), new VariableGet(valueVariable)]), 336 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
325 setter)..fileOffset = charOffset); 337 setter)..fileOffset = charOffset);
326 return makeLet( 338 return makeLet(
327 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); 339 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
328 } 340 }
329 341
330 Expression _finish(Expression body) { 342 ShadowExpression _finish(ShadowExpression body) {
331 return makeLet(receiverVariable, makeLet(indexVariable, body)); 343 return makeLet(receiverVariable, makeLet(indexVariable, body as Expression))
344 as ShadowExpression;
332 } 345 }
333 } 346 }
334 347
335 /// Special case of [IndexAccessor] to avoid creating an indirect access to 348 /// Special case of [IndexAccessor] to avoid creating an indirect access to
336 /// 'this'. 349 /// 'this'.
337 class ThisIndexAccessor extends Accessor { 350 class ThisIndexAccessor extends Accessor {
338 Expression index; 351 Expression index;
339 VariableDeclaration indexVariable; 352 VariableDeclaration indexVariable;
340 Procedure getter, setter; 353 Procedure getter, setter;
341 354
(...skipping 29 matching lines...) Expand all
371 var dummy = new VariableDeclaration.forValue(new MethodInvocation( 384 var dummy = new VariableDeclaration.forValue(new MethodInvocation(
372 new ThisExpression(), 385 new ThisExpression(),
373 indexSetName, 386 indexSetName,
374 new Arguments( 387 new Arguments(
375 <Expression>[indexAccess(), new VariableGet(valueVariable)]), 388 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
376 setter)); 389 setter));
377 return makeLet( 390 return makeLet(
378 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); 391 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
379 } 392 }
380 393
381 Expression _finish(Expression body) => makeLet(indexVariable, body); 394 ShadowExpression _finish(ShadowExpression body) =>
395 makeLet(indexVariable, body as Expression) as ShadowExpression;
382 } 396 }
383 397
384 class SuperIndexAccessor extends Accessor { 398 class SuperIndexAccessor extends Accessor {
385 Expression index; 399 Expression index;
386 VariableDeclaration indexVariable; 400 VariableDeclaration indexVariable;
387 Member getter, setter; 401 Member getter, setter;
388 402
389 SuperIndexAccessor(this.index, this.getter, this.setter); 403 SuperIndexAccessor(this.index, this.getter, this.setter);
390 404
391 indexAccess() { 405 indexAccess() {
(...skipping 25 matching lines...) Expand all
417 var valueVariable = new VariableDeclaration.forValue(value); 431 var valueVariable = new VariableDeclaration.forValue(value);
418 var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation( 432 var dummy = new VariableDeclaration.forValue(new SuperMethodInvocation(
419 indexSetName, 433 indexSetName,
420 new Arguments( 434 new Arguments(
421 <Expression>[indexAccess(), new VariableGet(valueVariable)]), 435 <Expression>[indexAccess(), new VariableGet(valueVariable)]),
422 setter)); 436 setter));
423 return makeLet( 437 return makeLet(
424 valueVariable, makeLet(dummy, new VariableGet(valueVariable))); 438 valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
425 } 439 }
426 440
427 Expression _finish(Expression body) { 441 ShadowExpression _finish(ShadowExpression body) {
428 return makeLet(indexVariable, body); 442 return makeLet(indexVariable, body as Expression) as ShadowExpression;
429 } 443 }
430 } 444 }
431 445
432 class StaticAccessor extends Accessor { 446 class StaticAccessor extends Accessor {
433 Member readTarget; 447 Member readTarget;
434 Member writeTarget; 448 Member writeTarget;
435 int charOffset; 449 int charOffset;
436 450
437 StaticAccessor(this.readTarget, this.writeTarget, this.charOffset); 451 StaticAccessor(this.readTarget, this.writeTarget, this.charOffset);
438 452
(...skipping 16 matching lines...) Expand all
455 469
456 _makeSimpleRead() => expression; 470 _makeSimpleRead() => expression;
457 471
458 _makeRead() { 472 _makeRead() {
459 value ??= new VariableDeclaration.forValue(expression); 473 value ??= new VariableDeclaration.forValue(expression);
460 return new VariableGet(value); 474 return new VariableGet(value);
461 } 475 }
462 476
463 _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value); 477 _makeWrite(Expression value, bool voidContext) => makeInvalidWrite(value);
464 478
465 Expression _finish(Expression body) => makeLet(value, body); 479 ShadowExpression _finish(ShadowExpression body) =>
480 makeLet(value, body as Expression) as ShadowExpression;
466 } 481 }
467 482
468 Expression makeLet(VariableDeclaration variable, Expression body) { 483 Expression makeLet(VariableDeclaration variable, Expression body) {
469 if (variable == null) return body; 484 if (variable == null) return body;
470 return new Let(variable, body); 485 return new Let(variable, body);
471 } 486 }
472 487
473 Expression makeBinary(Expression left, Name operator, Procedure interfaceTarget, 488 Expression makeBinary(Expression left, Name operator, Procedure interfaceTarget,
474 Expression right, int charOffset) { 489 Expression right, int charOffset) {
475 return new MethodInvocation( 490 return new MethodInvocation(
(...skipping 10 matching lines...) Expand all
486 501
487 VariableDeclaration makeOrReuseVariable(Expression value) { 502 VariableDeclaration makeOrReuseVariable(Expression value) {
488 // TODO: Devise a way to remember if a variable declaration was reused 503 // TODO: Devise a way to remember if a variable declaration was reused
489 // or is fresh (hence needs a let binding). 504 // or is fresh (hence needs a let binding).
490 return new VariableDeclaration.forValue(value); 505 return new VariableDeclaration.forValue(value);
491 } 506 }
492 507
493 Expression wrapInvalid(Expression e) { 508 Expression wrapInvalid(Expression e) {
494 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression()); 509 return new Let(new VariableDeclaration.forValue(e), new InvalidExpression());
495 } 510 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/kernel/builder_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