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

Side by Side Diff: pkg/fasta/lib/src/kernel/builder_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 library fasta.builder_accessors;
6
7 export 'frontend_accessors.dart' show
8 wrapInvalid;
9
10 import 'frontend_accessors.dart' show
11 Accessor;
12
13 import 'package:kernel/ast.dart';
14
15 import 'package:kernel/core_types.dart' show
16 CoreTypes;
17
18 import '../errors.dart' show
19 internalError;
20
21 import 'frontend_accessors.dart' as kernel show
22 IndexAccessor,
23 NullAwarePropertyAccessor,
24 PropertyAccessor,
25 StaticAccessor,
26 SuperPropertyAccessor,
27 ThisIndexAccessor,
28 ThisPropertyAccessor,
29 VariableAccessor;
30
31 import 'frontend_accessors.dart' show
32 buildIsNull,
33 makeLet;
34
35 import 'kernel_builder.dart' show
36 Builder,
37 KernelClassBuilder,
38 PrefixBuilder,
39 TypeDeclarationBuilder;
40
41 abstract class BuilderHelper {
42 Uri get uri;
43
44 CoreTypes get coreTypes;
45
46 Constructor lookupConstructor(Name name, {bool isSuper});
47
48 Expression toSuperMethodInvocation(MethodInvocation node);
49
50 Expression toValue(node);
51
52 Member lookupSuperMember(Name name, {bool isSetter: false});
53
54 builderToFirstExpression(Builder builder, String name, int charOffset);
55
56 finishSend(Object receiver, Arguments arguments, int charOffset);
57
58 Expression buildCompileTimeError(error, [int charOffset]);
59
60 Initializer buildCompileTimeErrorIntializer(error, [int charOffset]);
61
62 Expression buildStaticInvocation(Procedure target, Arguments arguments);
63
64 Expression buildProblemExpression(Builder builder, String name);
65 }
66
67 abstract class BuilderAccessor implements Accessor {
68 BuilderHelper get helper;
69
70 int get charOffset;
71
72 String get plainNameForRead;
73
74 Uri get uri => helper.uri;
75
76 CoreTypes get coreTypes => helper.coreTypes;
77
78 String get plainNameForWrite => plainNameForRead;
79
80 Expression buildForEffect() => buildSimpleRead();
81
82 Initializer buildFieldInitializer(
83 Map<String, FieldInitializer> initializers) {
84 // TODO(ahe): This error message is really bad.
85 return helper.buildCompileTimeErrorIntializer(
86 "Can't use $plainNameForRead here.", charOffset);
87 }
88
89 Expression makeInvalidRead() {
90 return throwNoSuchMethodError(plainNameForRead, new Arguments.empty(), uri,
91 charOffset, coreTypes, isGetter: true);
92 }
93
94 Expression makeInvalidWrite(Expression value) {
95 return throwNoSuchMethodError(plainNameForWrite,
96 new Arguments(<Expression>[value]), uri, charOffset, coreTypes,
97 isSetter: true);
98 }
99
100 Expression doInvocation(int charOffset, Arguments arguments);
101
102 buildPropertyAccess(IncompleteSend send, bool isNullAware) {
103 if (send is SendAccessor) {
104 return buildMethodInvocation(buildSimpleRead(), send.name, send.arguments,
105 charOffset, isNullAware: isNullAware);
106 } else {
107 return PropertyAccessor.make(helper, charOffset, buildSimpleRead(),
108 send.name, null, null, isNullAware);
109 }
110 }
111
112 Expression buildThrowNoSuchMethodError(Arguments arguments) {
113 bool isGetter = false;
114 if (arguments == null) {
115 arguments = new Arguments.empty();
116 isGetter = true;
117 }
118 return throwNoSuchMethodError(plainNameForWrite, arguments, uri, charOffset,
119 coreTypes, isGetter: isGetter);
120 }
121
122 bool get isThisPropertyAccessor => false;
123 }
124
125 abstract class CompileTimeErrorAccessor implements Accessor {
126 Expression buildError();
127
128 Name get name => internalError("Unsupported operation.");
129
130 String get plainNameForRead => name.name;
131
132 withReceiver(Object receiver, {bool isNullAware}) => this;
133
134 Initializer buildFieldInitializer(
135 Map<String, FieldInitializer> initializers) {
136 return new LocalInitializer(new VariableDeclaration.forValue(buildError()));
137 }
138
139 doInvocation(int charOffset, Arguments arguments) => this;
140
141 buildPropertyAccess(IncompleteSend send, bool isNullAware) => this;
142
143 buildThrowNoSuchMethodError(Arguments arguments) => this;
144
145 Expression buildAssignment(Expression value, {bool voidContext: false}) {
146 return buildError();
147 }
148
149 Expression buildCompoundAssignment(Name binaryOperator, Expression value,
150 {bool voidContext: false, Procedure interfaceTarget}) {
151 return buildError();
152 }
153
154 Expression buildPrefixIncrement(Name binaryOperator,
155 {bool voidContext: false, Procedure interfaceTarget}) {
156 return buildError();
157 }
158
159 Expression buildPostfixIncrement(Name binaryOperator,
160 {bool voidContext: false, Procedure interfaceTarget}) {
161 return buildError();
162 }
163
164 Expression buildNullAwareAssignment(Expression value, DartType type,
165 {bool voidContext: false}) {
166 return buildError();
167 }
168
169 Expression buildSimpleRead() => buildError();
170
171 Expression makeInvalidRead() => buildError();
172
173 Expression makeInvalidWrite(Expression value) => buildError();
174 }
175
176 class ThisAccessor extends BuilderAccessor {
177 final BuilderHelper helper;
178
179 final int charOffset;
180
181 final bool isInitializer;
182
183 final bool isSuper;
184
185 ThisAccessor(this.helper, this.charOffset, this.isInitializer,
186 {this.isSuper: false});
187
188 String get plainNameForRead => internalError(isSuper ? "super" : "this");
189
190 Expression buildSimpleRead() {
191 if (!isSuper) {
192 return new ThisExpression();
193 } else {
194 return helper.buildCompileTimeError(
195 "Can't use `super` as an expression.", charOffset);
196 }
197 }
198
199 Initializer buildFieldInitializer(
200 Map<String, FieldInitializer> initializers) {
201 String keyword = isSuper ? "super" : "this";
202 return helper.buildCompileTimeErrorIntializer(
203 "Can't use '$keyword' here, did you mean '$keyword()'?", charOffset);
204 }
205
206 buildPropertyAccess(IncompleteSend send, bool isNullAware) {
207 if (isInitializer && send is SendAccessor) {
208 return buildConstructorInitializer(
209 send.charOffset, send.name, send.arguments);
210 }
211 if (send is SendAccessor) {
212 // Notice that 'this' or 'super' can't be null. So we can ignore the
213 // value of [isNullAware].
214 MethodInvocation result = buildMethodInvocation(new ThisExpression(),
215 send.name, send.arguments, charOffset);
216 return isSuper ? helper.toSuperMethodInvocation(result) : result;
217 } else {
218 if (isSuper) {
219 Member getter = helper.lookupSuperMember(send.name);
220 Member setter = helper.lookupSuperMember(send.name, isSetter: true);
221 return new SuperPropertyAccessor(helper, charOffset, send.name, getter,
222 setter);
223 } else {
224 return new ThisPropertyAccessor(helper, charOffset, send.name, null,
225 null);
226 }
227 }
228 }
229
230 doInvocation(int charOffset, Arguments arguments) {
231 if (isInitializer) {
232 return buildConstructorInitializer(charOffset, new Name(""), arguments);
233 } else {
234 return buildMethodInvocation(new ThisExpression(), new Name("call"),
235 arguments, charOffset);
236 }
237 }
238
239 Initializer buildConstructorInitializer(int charOffset, Name name,
240 Arguments arguments) {
241 Constructor constructor = helper.lookupConstructor(name, isSuper: isSuper);
242 Initializer result;
243 if (constructor == null) {
244 result = new LocalInitializer(
245 new VariableDeclaration.forValue(
246 throwNoSuchMethodError(
247 name.name, arguments, uri, charOffset, coreTypes,
248 isSuper: isSuper)));
249 } else if (isSuper) {
250 result = new SuperInitializer(constructor, arguments);
251 } else {
252 result = new RedirectingInitializer(constructor, arguments);
253 }
254 return result
255 ..fileOffset = charOffset;
256 }
257
258 Expression buildAssignment(Expression value, {bool voidContext: false}) {
259 return internalError("");
260 }
261
262 Expression buildNullAwareAssignment(Expression value, DartType type,
263 {bool voidContext: false}) {
264 return internalError("");
265 }
266
267 Expression buildCompoundAssignment(Name binaryOperator, Expression value,
268 {bool voidContext: false, Procedure interfaceTarget}) {
269 return internalError("");
270 }
271
272 Expression buildPrefixIncrement(Name binaryOperator,
273 {bool voidContext: false, Procedure interfaceTarget}) {
274 return internalError("");
275 }
276
277 Expression buildPostfixIncrement(Name binaryOperator,
278 {bool voidContext: false, Procedure interfaceTarget}) {
279 return internalError("");
280 }
281
282 toString() => "ThisAccessor($charOffset${isSuper ? ', super' : ''})";
283 }
284
285 abstract class IncompleteSend extends BuilderAccessor {
286 final BuilderHelper helper;
287
288 final int charOffset;
289
290 final Name name;
291
292 IncompleteSend(this.helper, this.charOffset, this.name);
293
294 withReceiver(Object receiver, {bool isNullAware});
295 }
296
297 class IncompleteError extends IncompleteSend with CompileTimeErrorAccessor {
298 final Object error;
299
300 IncompleteError(BuilderHelper helper, int charOffset, this.error)
301 : super(helper, charOffset, null);
302
303 Expression buildError() {
304 return helper.buildCompileTimeError(error, charOffset);
305 }
306 }
307
308 class SendAccessor extends IncompleteSend {
309 final Arguments arguments;
310
311 SendAccessor(BuilderHelper helper, int charOffset, Name name, this.arguments)
312 : super(helper, charOffset, name) {
313 assert(arguments != null);
314 }
315
316 String get plainNameForRead => name.name;
317
318 Expression buildSimpleRead() {
319 return internalError("Unhandled");
320 }
321
322 Expression buildAssignment(Expression value, {bool voidContext: false}) {
323 return internalError("Unhandled");
324 }
325
326 withReceiver(Object receiver, {bool isNullAware: false}) {
327 if (receiver is TypeDeclarationBuilder) {
328 /// `SomeType?.toString` is the same as `SomeType.toString`, not
329 /// `(SomeType).toString`.
330 isNullAware = false;
331 }
332 if (receiver is BuilderAccessor) {
333 return receiver.buildPropertyAccess(this, isNullAware);
334 }
335 if (receiver is PrefixBuilder) {
336 PrefixBuilder prefix = receiver;
337 receiver = helper.builderToFirstExpression(
338 prefix.exports[name.name], "${prefix.name}.${name.name}", charOffset);
339 return helper.finishSend(receiver, arguments, charOffset);
340 }
341 Expression result;
342 if (receiver is KernelClassBuilder) {
343 Builder builder = receiver.findStaticBuilder(name.name);
344 if (builder == null) {
345 return buildThrowNoSuchMethodError(arguments);
346 }
347 if (builder.hasProblem) {
348 result = helper.buildProblemExpression(builder, name.name);
349 } else {
350 Member target = builder.target;
351 if (target != null) {
352 if (target is Field) {
353 result = buildMethodInvocation(new StaticGet(target),
354 new Name("call"), arguments, charOffset,
355 isNullAware: isNullAware);
356 } else {
357 result = helper.buildStaticInvocation(target, arguments);
358 }
359 } else {
360 result = buildThrowNoSuchMethodError(arguments);
361 }
362 }
363 } else {
364 result = buildMethodInvocation(helper.toValue(receiver), name,
365 arguments, charOffset, isNullAware: isNullAware);
366 }
367 return result..fileOffset = charOffset;
368 }
369
370 Expression buildNullAwareAssignment(Expression value, DartType type,
371 {bool voidContext: false}) {
372 return internalError("");
373 }
374
375 Expression buildCompoundAssignment(Name binaryOperator, Expression value,
376 {bool voidContext: false, Procedure interfaceTarget}) {
377 return internalError("");
378 }
379
380 Expression buildPrefixIncrement(Name binaryOperator,
381 {bool voidContext: false, Procedure interfaceTarget}) {
382 return internalError("Unhandled");
383 }
384
385 Expression buildPostfixIncrement(Name binaryOperator,
386 {bool voidContext: false, Procedure interfaceTarget}) {
387 return internalError("Unhandled");
388 }
389
390 Expression doInvocation(int charOffset, Arguments arguments) {
391 return internalError("Unhandled");
392 }
393
394 toString() => "SendAccessor($charOffset, $name, $arguments)";
395 }
396
397 class IncompletePropertyAccessor extends IncompleteSend {
398 IncompletePropertyAccessor(BuilderHelper helper, int charOffset, Name name)
399 : super(helper, charOffset, name);
400
401 String get plainNameForRead => name.name;
402
403 Expression buildSimpleRead() => internalError("Unhandled");
404
405 Expression buildAssignment(Expression value, {bool voidContext: false}) {
406 return internalError("Unhandled");
407 }
408
409 withReceiver(Object receiver, {bool isNullAware: false}) {
410 if (receiver is TypeDeclarationBuilder) {
411 /// For reasons beyond comprehension, `SomeType?.toString` is the same as
412 /// `SomeType.toString`, not `(SomeType).toString`. WTAF!?!
413 //
414 isNullAware = false;
415 }
416 if (receiver is BuilderAccessor) {
417 return receiver.buildPropertyAccess(this, isNullAware);
418 }
419 if (receiver is PrefixBuilder) {
420 PrefixBuilder prefix = receiver;
421 return helper.builderToFirstExpression(
422 prefix.exports[name.name], name.name, charOffset);
423 }
424 if (receiver is KernelClassBuilder) {
425 Builder builder = receiver.findStaticBuilder(name.name);
426 Member getter = builder?.target;
427 Member setter;
428 if (builder == null) {
429 builder = receiver.findStaticBuilder(name.name, isSetter: true);
430 if (builder == null) {
431 return buildThrowNoSuchMethodError(null);
432 }
433 }
434 if (builder.hasProblem) {
435 return helper.buildProblemExpression(builder, name.name)
436 ..fileOffset = charOffset;
437 }
438 if (getter is Field) {
439 if (!getter.isFinal && !getter.isConst) {
440 setter = getter;
441 }
442 } else if (getter is Procedure) {
443 if (getter.isGetter) {
444 builder = receiver.findStaticBuilder(name.name, isSetter: true);
445 if (builder != null && !builder.hasProblem) {
446 setter = builder.target;
447 }
448 }
449 }
450 if (getter == null) {
451 return internalError("no getter for $name");
452 }
453 return new StaticAccessor(helper, charOffset, getter, setter);
454 }
455 return PropertyAccessor.make(helper, charOffset, helper.toValue(receiver),
456 name, null, null, isNullAware);
457 }
458
459 Expression buildNullAwareAssignment(Expression value, DartType type,
460 {bool voidContext: false}) {
461 return internalError("Unhandled");
462 }
463
464 Expression buildCompoundAssignment(Name binaryOperator, Expression value,
465 {bool voidContext: false, Procedure interfaceTarget}) {
466 return internalError("Unhandled");
467 }
468
469 Expression buildPrefixIncrement(Name binaryOperator,
470 {bool voidContext: false, Procedure interfaceTarget}) {
471 return internalError("Unhandled");
472 }
473
474 Expression buildPostfixIncrement(Name binaryOperator,
475 {bool voidContext: false, Procedure interfaceTarget}) {
476 return internalError("Unhandled");
477 }
478
479 Expression doInvocation(int charOffset, Arguments arguments) {
480 return internalError("Unhandled");
481 }
482
483 toString() => "IncompletePropertyAccessor($charOffset, $name)";
484 }
485
486 class IndexAccessor extends kernel.IndexAccessor with BuilderAccessor {
487 final BuilderHelper helper;
488
489 final int charOffset;
490
491 IndexAccessor.internal(this.helper, this.charOffset, Expression receiver,
492 Expression index, Procedure getter, Procedure setter)
493 : super.internal(receiver, index, getter, setter);
494
495 String get plainNameForRead => "[]";
496
497 String get plainNameForWrite => "[]=";
498
499 Expression doInvocation(int charOffset, Arguments arguments) {
500 return buildMethodInvocation(buildSimpleRead(), new Name("call"), arguments,
501 charOffset);
502 }
503
504 toString() => "IndexAccessor()";
505
506 static BuilderAccessor make(BuilderHelper helper, int charOffset,
507 Expression receiver, Expression index, Procedure getter,
508 Procedure setter) {
509 if (receiver is ThisExpression) {
510 return new ThisIndexAccessor(helper, charOffset, index, getter, setter);
511 } else {
512 return new IndexAccessor.internal(helper, charOffset, receiver, index,
513 getter, setter);
514 }
515 }
516 }
517
518 class PropertyAccessor extends kernel.PropertyAccessor with BuilderAccessor {
519 final BuilderHelper helper;
520
521 final int charOffset;
522
523 PropertyAccessor.internal(this.helper, this.charOffset, Expression receiver,
524 Name name, Member getter, Member setter)
525 : super.internal(receiver, name, getter, setter);
526
527 String get plainNameForRead => name.name;
528
529 bool get isThisPropertyAccessor => receiver is ThisExpression;
530
531 Expression doInvocation(int charOffset, Arguments arguments) {
532 return buildMethodInvocation(receiver, name, arguments, charOffset);
533 }
534
535 toString() => "PropertyAccessor()";
536
537 static BuilderAccessor make(BuilderHelper helper, int charOffset,
538 Expression receiver, Name name, Member getter, Member setter,
539 bool isNullAware) {
540 if (receiver is ThisExpression) {
541 return new ThisPropertyAccessor(helper, charOffset, name, getter, setter);
542 } else {
543 return isNullAware
544 ? new NullAwarePropertyAccessor(helper, charOffset, receiver, name,
545 getter, setter, null)
546 : new PropertyAccessor.internal(helper, charOffset, receiver, name,
547 getter, setter);
548 }
549 }
550 }
551
552 class StaticAccessor extends kernel.StaticAccessor with BuilderAccessor {
553 final BuilderHelper helper;
554
555 final int charOffset;
556
557 StaticAccessor(this.helper, this.charOffset, Member readTarget,
558 Member writeTarget)
559 : super(readTarget, writeTarget) {
560 assert(readTarget != null || writeTarget != null);
561 }
562
563 String get plainNameForRead => (readTarget ?? writeTarget).name.name;
564
565 Expression doInvocation(int charOffset, Arguments arguments) {
566 if (readTarget == null || isFieldOrGetter(readTarget)) {
567 return buildMethodInvocation(buildSimpleRead(), new Name("call"),
568 arguments, charOffset);
569 } else {
570 return helper.buildStaticInvocation(readTarget, arguments)
571 ..fileOffset = charOffset;
572 }
573 }
574
575 toString() => "StaticAccessor()";
576 }
577
578 class SuperPropertyAccessor extends kernel.SuperPropertyAccessor
579 with BuilderAccessor {
580 final BuilderHelper helper;
581
582 final int charOffset;
583
584 SuperPropertyAccessor(this.helper, this.charOffset, Name name, Member getter,
585 Member setter)
586 : super(name, getter, setter);
587
588 String get plainNameForRead => name.name;
589
590 Expression doInvocation(int charOffset, Arguments arguments) {
591 if (getter == null || isFieldOrGetter(getter)) {
592 return buildMethodInvocation(buildSimpleRead(), new Name("call"),
593 arguments, charOffset);
594 } else {
595 return new DirectMethodInvocation(new ThisExpression(), getter, arguments)
596 ..fileOffset = charOffset;
597 }
598 }
599
600 toString() => "SuperPropertyAccessor()";
601 }
602
603 class ThisIndexAccessor extends kernel.ThisIndexAccessor with BuilderAccessor {
604 final BuilderHelper helper;
605
606 final int charOffset;
607
608 ThisIndexAccessor(this.helper, this.charOffset, Expression index,
609 Procedure getter, Procedure setter)
610 : super(index, getter, setter);
611
612 String get plainNameForRead => "[]";
613
614 String get plainNameForWrite => "[]=";
615
616 Expression doInvocation(int charOffset, Arguments arguments) {
617 return buildMethodInvocation(buildSimpleRead(), new Name("call"), arguments,
618 charOffset);
619 }
620
621 toString() => "ThisIndexAccessor()";
622 }
623
624 class ThisPropertyAccessor extends kernel.ThisPropertyAccessor
625 with BuilderAccessor {
626 final BuilderHelper helper;
627
628 final int charOffset;
629
630 ThisPropertyAccessor(this.helper, this.charOffset, Name name, Member getter,
631 Member setter)
632 : super(name, getter, setter);
633
634 String get plainNameForRead => name.name;
635
636 bool get isThisPropertyAccessor => true;
637
638 Expression doInvocation(int charOffset, Arguments arguments) {
639 Member interfaceTarget = getter;
640 if (interfaceTarget is Field) {
641 // TODO(ahe): In strong mode we should probably rewrite this to
642 // `this.name.call(arguments)`.
643 interfaceTarget = null;
644 }
645 return buildMethodInvocation(new ThisExpression(), name, arguments,
646 charOffset);
647 }
648
649 toString() => "ThisPropertyAccessor()";
650 }
651
652 class NullAwarePropertyAccessor extends kernel.NullAwarePropertyAccessor
653 with BuilderAccessor {
654 final BuilderHelper helper;
655
656 final int charOffset;
657
658 NullAwarePropertyAccessor(this.helper, this.charOffset, Expression receiver,
659 Name name, Member getter, Member setter, DartType type)
660 : super(receiver, name, getter, setter, type);
661
662 String get plainNameForRead => name.name;
663
664 Expression doInvocation(int charOffset, Arguments arguments) {
665 return internalError("Not implemented yet.");
666 }
667
668 toString() => "NullAwarePropertyAccessor()";
669 }
670
671
672 class VariableAccessor extends kernel.VariableAccessor
673 with BuilderAccessor {
674 final BuilderHelper helper;
675
676 final int charOffset;
677
678 VariableAccessor(this.helper, this.charOffset, VariableDeclaration variable,
679 [DartType promotedType])
680 : super.internal(variable, promotedType);
681
682 String get plainNameForRead => variable.name;
683
684 Expression doInvocation(int charOffset, Arguments arguments) {
685 return buildMethodInvocation(buildSimpleRead(), new Name("call"), arguments,
686 charOffset);
687 }
688
689 toString() => "VariableAccessor()";
690 }
691
692 Expression throwNoSuchMethodError(String name, Arguments arguments, Uri uri,
693 int charOffset, CoreTypes coreTypes,
694 {bool isSuper: false, isGetter: false, isSetter: false}) {
695 print("$uri:$charOffset: method not found: '$name'.");
696 Constructor constructor = coreTypes.getCoreClass(
697 "dart:core", "NoSuchMethodError").constructors.first;
698 return new Throw(new ConstructorInvocation(
699 constructor,
700 new Arguments(<Expression>[
701 new NullLiteral(),
702 new SymbolLiteral(name),
703 new ListLiteral(arguments.positional),
704 new MapLiteral(arguments.named.map((arg) {
705 return new MapEntry(new SymbolLiteral(arg.name), arg.value);
706 }).toList()),
707 new NullLiteral()])));
708 }
709
710 bool isFieldOrGetter(Member member) {
711 return member is Field || (member is Procedure && member.isGetter);
712 }
713
714 Expression buildMethodInvocation(Expression receiver, Name name,
715 Arguments arguments, int charOffset, {bool isNullAware: false}) {
716 if (isNullAware) {
717 VariableDeclaration variable = new VariableDeclaration.forValue(receiver);
718 return makeLet(
719 variable,
720 new ConditionalExpression(
721 buildIsNull(new VariableGet(variable)),
722 new NullLiteral(),
723 new MethodInvocation(new VariableGet(variable), name, arguments)
724 ..fileOffset = charOffset,
725 const DynamicType()));
726 } else {
727 return new MethodInvocation(receiver, name, arguments)
728 ..fileOffset = charOffset;
729 }
730 }
OLDNEW
« no previous file with comments | « pkg/fasta/lib/src/kernel/body_builder.dart ('k') | pkg/fasta/lib/src/kernel/frontend_accessors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698