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

Side by Side Diff: pkg/compiler/lib/src/kernel/kernel_visitor.dart

Issue 2265383002: Copy Rasta visitor to dart2js. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: missed some renames Created 4 years, 3 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
« no previous file with comments | « pkg/compiler/lib/src/kernel/kernel.dart ('k') | pkg/compiler/lib/src/kernel/unavailable.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.md file.
4
5 import 'package:kernel/ast.dart' as ir;
6 import 'package:kernel/frontend/accessors.dart'
7 show
8 Accessor,
9 IndexAccessor,
10 NullAwarePropertyAccessor,
11 PropertyAccessor,
12 ReadOnlyAccessor,
13 StaticAccessor,
14 SuperIndexAccessor,
15 SuperPropertyAccessor,
16 ThisPropertyAccessor,
17 VariableAccessor,
18 buildIsNull,
19 makeBinary,
20 makeLet,
21 makeOrReuseVariable;
22
23 import '../constants/expressions.dart'
24 show
25 BoolFromEnvironmentConstantExpression,
26 ConstantExpression,
27 ConstructedConstantExpression,
28 IntFromEnvironmentConstantExpression,
29 StringFromEnvironmentConstantExpression,
30 TypeConstantExpression;
31 import '../dart_types.dart' show DartType, InterfaceType;
32 import '../diagnostics/spannable.dart' show Spannable;
33 import '../elements/elements.dart'
34 show
35 AstElement,
36 AsyncMarker,
37 ClassElement,
38 ConstructorElement,
39 Element,
40 FieldElement,
41 FunctionElement,
42 FunctionSignature,
43 GetterElement,
44 InitializingFormalElement,
45 JumpTarget,
46 LocalElement,
47 LocalFunctionElement,
48 LocalVariableElement,
49 MethodElement,
50 Name,
51 ParameterElement,
52 PrefixElement,
53 TypeVariableElement;
54 import '../resolution/operators.dart'
55 show AssignmentOperator, BinaryOperator, IncDecOperator, UnaryOperator;
56 import '../resolution/semantic_visitor.dart'
57 show
58 BaseImplementationOfCompoundsMixin,
59 BaseImplementationOfLocalsMixin,
60 BaseImplementationOfSetIfNullsMixin,
61 BaseImplementationOfStaticsMixin,
62 CompoundGetter,
63 CompoundKind,
64 CompoundRhs,
65 CompoundSetter,
66 SemanticDeclarationResolvedMixin,
67 SemanticDeclarationVisitor,
68 SemanticSendResolvedMixin,
69 SemanticSendVisitor,
70 SemanticVisitor;
71 import '../resolution/send_resolver.dart' show DeclarationResolverMixin;
72 import '../resolution/send_structure.dart'
73 show
74 InitializerStructure,
75 InitializersStructure,
76 ParameterStructure,
77 VariableStructure;
78 import '../resolution/tree_elements.dart' show TreeElements;
79 import '../tree/tree.dart'
80 show
81 Assert,
82 AsyncForIn,
83 Await,
84 Block,
85 BreakStatement,
86 Cascade,
87 CascadeReceiver,
88 CaseMatch,
89 CatchBlock,
90 Conditional,
91 ConditionalUri,
92 ContinueStatement,
93 DoWhile,
94 DottedName,
95 EmptyStatement,
96 Enum,
97 Expression,
98 ExpressionStatement,
99 For,
100 ForIn,
101 FunctionDeclaration,
102 FunctionExpression,
103 Identifier,
104 If,
105 Label,
106 LabeledStatement,
107 LiteralBool,
108 LiteralDouble,
109 LiteralInt,
110 LiteralList,
111 LiteralMap,
112 LiteralMapEntry,
113 LiteralNull,
114 LiteralString,
115 LiteralSymbol,
116 Metadata,
117 NamedArgument,
118 NewExpression,
119 Node,
120 NodeList,
121 Operator,
122 ParenthesizedExpression,
123 RedirectingFactoryBody,
124 Rethrow,
125 Return,
126 Send,
127 SendSet,
128 Statement,
129 StringInterpolation,
130 StringInterpolationPart,
131 StringJuxtaposition,
132 SwitchCase,
133 SwitchStatement,
134 SyncForIn,
135 Throw,
136 TryStatement,
137 TypeAnnotation,
138 TypeVariable,
139 VariableDefinitions,
140 While,
141 Yield;
142 import '../universe/call_structure.dart' show CallStructure;
143 import '../universe/selector.dart' show Selector;
144 import '../util/util.dart' show Link;
145 import 'error.dart' show KernelError;
146 import 'fall_through_visitor.dart' show fallsThrough;
147 import 'kernel.dart' show ConstructorTarget, Kernel;
148 import 'unavailable.dart' show UnavailableVisitor;
149 import 'unresolved.dart' show RastaUnresolved;
150
151 /// Translates dart2js AST nodes [Node] into Kernel IR [ir.TreeNode].
152 ///
153 /// Most methods in this class have a prefix that follows these conventions:
154 ///
155 /// * `visit` for overridden visitor methods.
156 /// * `handle` for methods that implement common behavior for several `visit`
157 /// methods. These methods are called by `visit` methods implemented by
158 /// various mixins below.
159 /// * `build` helper method that builds a new Kernel IR tree.
160 /// * `get` helper method that use a cache to build exactly one Kernel IR
161 /// tree for a given element.
162 ///
163 /// We reserve the prefixes `visit` and `handle` for superclasses of this
164 /// class. So those methods should always have an @override annotation. Use
165 /// `build` instead of `handle` when adding a new helper method to this class.
166 class KernelVisitor extends Object
167 with
168 SemanticSendResolvedMixin,
169 BaseImplementationOfStaticsMixin,
170 BaseImplementationOfLocalsMixin,
171 BaseImplementationOfCompoundsMixin,
172 BaseImplementationOfSetIfNullsMixin,
173 SemanticDeclarationResolvedMixin,
174 DeclarationResolverMixin,
175 UnavailableVisitor,
176 RastaUnresolved,
177 KernelError
178 implements
179 SemanticVisitor,
180 SemanticSendVisitor,
181 SemanticDeclarationVisitor {
182 TreeElements elements;
183 AstElement currentElement;
184 final Kernel kernel;
185
186 final Map<JumpTarget, ir.LabeledStatement> continueTargets =
187 <JumpTarget, ir.LabeledStatement>{};
188
189 final Map<JumpTarget, ir.SwitchCase> continueSwitchTargets =
190 <JumpTarget, ir.SwitchCase>{};
191
192 final Map<JumpTarget, ir.LabeledStatement> breakTargets =
193 <JumpTarget, ir.LabeledStatement>{};
194
195 final Map<LocalElement, ir.VariableDeclaration> locals =
196 <LocalElement, ir.VariableDeclaration>{};
197
198 final Map<CascadeReceiver, ir.VariableGet> cascadeReceivers =
199 <CascadeReceiver, ir.VariableGet>{};
200
201 bool isVoidContext = false;
202
203 KernelVisitor(this.currentElement, this.elements, this.kernel);
204
205 KernelVisitor get sendVisitor => this;
206
207 KernelVisitor get declVisitor => this;
208
209 ir.TreeNode visitForValue(Expression node) {
210 bool wasVoidContext = isVoidContext;
211 isVoidContext = false;
212 try {
213 return node?.accept(this);
214 } finally {
215 isVoidContext = wasVoidContext;
216 }
217 }
218
219 ir.TreeNode visitForEffect(Expression node) {
220 bool wasVoidContext = isVoidContext;
221 isVoidContext = true;
222 try {
223 return node?.accept(this);
224 } finally {
225 isVoidContext = wasVoidContext;
226 }
227 }
228
229 ir.TreeNode visitWithCurrentContext(Expression node) => node?.accept(this);
230
231 withCurrentElement(AstElement element, f()) {
232 assert(element.library == kernel.compiler.currentElement.library);
233 Element previousElement = currentElement;
234 currentElement = element;
235 try {
236 return f();
237 } finally {
238 currentElement = previousElement;
239 }
240 }
241
242 ir.DartType computeType(TypeAnnotation node) {
243 if (node == null) return const ir.DynamicType();
244 return kernel.typeToIr(elements.getType(node));
245 }
246
247 // This works around a bug in dart2js.
248 // TODO(ahe): Fix the bug in dart2js and remove this function.
249 ir.DartType typeToIrHack(DartType type) {
250 if (currentElement.isSynthesized &&
251 currentElement.enclosingClass.isMixinApplication &&
252 !kernel.hasHierarchyProblem(currentElement.enclosingClass)) {
253 // Dart2js doesn't compute the correct functionSignature for synthetic
254 // constructors in mixin applications. So we compute the correct type:
255 // First, find the first superclass that isn't a mixin.
256 ClassElement superclass = currentElement.enclosingClass.superclass;
257 while (superclass.isMixinApplication) {
258 superclass = superclass.superclass;
259 }
260 // Then translate the "this type" of the mixin application to its
261 // supertype with the correct type arguments.
262 //
263 // Consider this example:
264 //
265 // class Super<S> {}
266 // class Sub<T> extends Object with Super<T> {}
267 //
268 // Here the problem is that dart2js has created a constructor that refers
269 // to S (not T) in Sub (for example, the return type of the constructor
270 // is Super<S> and it should be Sub<T>, but we settle for Super<T> for
271 // now). So we need to translate Sub<T> to an instance of Super, which is
272 // Super<T> (not Super<S>).
273 InterfaceType supertype =
274 currentElement.enclosingClass.asInstanceOf(superclass);
275 // Once we have [supertype], we know how to substitute S with T: the type
276 // arguments of [supertype] corresponds to T, and the type variables of
277 // its element correspond to S.
278 type =
279 type.subst(supertype.typeArguments, supertype.element.typeVariables);
280 }
281 return kernel.typeToIr(type);
282 }
283
284 // TODO(ahe): Hack. Fix dart2js instead.
285 ir.Name nameToIrName(Name name) {
286 assert(!name.isPrivate ||
287 name.library.implementation == currentElement.library.implementation);
288 return kernel.irName(name.text, currentElement);
289 }
290
291 List<ir.DartType> computeTypesFromTypes(NodeList nodes, {int expected}) {
292 if (expected == null) {
293 throw "[expected] is null";
294 }
295 List<ir.DartType> types = new List<ir.DartType>(expected);
296 Iterator<Node> iterator = nodes?.iterator;
297 for (int i = 0; i < expected; i++) {
298 TypeAnnotation type = null;
299 if (iterator != null && iterator.moveNext()) {
300 type = iterator.current;
301 }
302 types[i] = computeType(type);
303 }
304 if (iterator != null && iterator.moveNext()) {
305 // Should already have been reported by resolution.
306 // TODO(ahe): Delete this debug message.
307 kernel.debugMessage(iterator.current, "Extra type arguments.");
308 }
309 return types;
310 }
311
312 ir.DartType computeTypeFromTypes(NodeList node) {
313 return computeTypesFromTypes(node, expected: 1).single;
314 }
315
316 ir.MethodInvocation buildInvokeSelector(
317 ir.Expression receiver, Selector selector, ir.Arguments arguments) {
318 return new ir.MethodInvocation(
319 receiver, nameToIrName(selector.memberName), arguments);
320 }
321
322 ir.MethodInvocation buildCall(
323 ir.Expression receiver, CallStructure callStructure, NodeList arguments) {
324 return buildInvokeSelector(
325 receiver, callStructure.callSelector, buildArguments(arguments));
326 }
327
328 @override
329 ir.Expression visitIdentifier(Identifier node) {
330 // TODO(ahe): Shouldn't have to override this method, but
331 // [SemanticSendResolvedMixin.visitIdentifier] may return `null` on errors.
332 if (node.isThis()) {
333 return sendVisitor.visitThisGet(node, null);
334 } else {
335 return new ir.InvalidExpression();
336 }
337 }
338
339 @override
340 ir.InvalidExpression handleUnresolved(Node node) {
341 return new ir.InvalidExpression();
342 }
343
344 @override
345 ir.Expression handleError(Node node) => new ir.InvalidExpression();
346
347 @override
348 void apply(Node node, _) {
349 throw new UnsupportedError("apply");
350 }
351
352 @override
353 void previsitDeferredAccess(Send node, PrefixElement prefix, _) {}
354
355 @override
356 internalError(Spannable spannable, String message) {
357 kernel.internalError(spannable, message);
358 }
359
360 @override
361 applyParameters(NodeList parameters, _) {
362 throw new UnsupportedError("applyParameters");
363 }
364
365 @override
366 applyInitializers(FunctionExpression constructor, _) {
367 throw new UnsupportedError("applyInitializers");
368 }
369
370 @override
371 ir.AssertStatement visitAssert(Assert node) {
372 return new ir.AssertStatement(
373 visitForValue(node.condition), visitForValue(node.message));
374 }
375
376 ir.LabeledStatement getBreakTarget(JumpTarget target) {
377 return breakTargets.putIfAbsent(
378 target, () => new ir.LabeledStatement(null));
379 }
380
381 ir.LabeledStatement getContinueTarget(JumpTarget target) {
382 return continueTargets.putIfAbsent(
383 target, () => new ir.LabeledStatement(null));
384 }
385
386 ir.SwitchCase getContinueSwitchTarget(JumpTarget target) {
387 return continueSwitchTargets[target];
388 }
389
390 ir.Statement buildBreakTarget(
391 ir.Statement statement, Node node, JumpTarget jumpTarget) {
392 assert(node.isValidBreakTarget());
393 assert(jumpTarget == elements.getTargetDefinition(node));
394 if (jumpTarget != null && jumpTarget.isBreakTarget) {
395 ir.LabeledStatement breakTarget = getBreakTarget(jumpTarget);
396 breakTarget.body = statement;
397 statement.parent = breakTarget;
398 return breakTarget;
399 } else {
400 return statement;
401 }
402 }
403
404 ir.Statement buildContinueTarget(
405 ir.Statement statement, Node node, JumpTarget jumpTarget) {
406 assert(node.isValidContinueTarget());
407 assert(jumpTarget == elements.getTargetDefinition(node));
408 if (jumpTarget != null && jumpTarget.isContinueTarget) {
409 ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget);
410 continueTarget.body = statement;
411 statement.parent = continueTarget;
412 return continueTarget;
413 } else {
414 return statement;
415 }
416 }
417
418 ir.Statement buildForInCommon(
419 ForIn node, ir.VariableDeclaration variable, ir.Statement body,
420 {bool isAsync}) {
421 ir.Expression iterable = visitForValue(node.expression);
422 JumpTarget jumpTarget = elements.getTargetDefinition(node);
423 body = buildContinueTarget(body, node, jumpTarget);
424 return buildBreakTarget(
425 new ir.ForInStatement(variable, iterable, body, isAsync: isAsync),
426 node,
427 jumpTarget);
428 }
429
430 /// Builds a for-in statement for this case:
431 ///
432 /// for (constOrVarOrType loopVariable in expression) body
433 ir.Statement buildForInWithDeclaration(
434 ForIn node, VariableDefinitions declaration,
435 {bool isAsync}) {
436 if (declaration.definitions.slowLength() != 1) {
437 // It's not legal to declare more than one variable in a for-in loop.
438 return new ir.InvalidStatement();
439 }
440 ir.VariableDeclaration variable = declaration.accept(this);
441 return buildForInCommon(node, variable, buildStatementInBlock(node.body),
442 isAsync: isAsync);
443 }
444
445 Accessor buildStaticAccessor(Element getter, [Element setter]) {
446 if (setter == null &&
447 getter != null &&
448 getter.isField &&
449 !getter.isFinal &&
450 !getter.isConst) {
451 setter = getter;
452 }
453 return new StaticAccessor(
454 (getter == null) ? null : kernel.elementToIr(getter),
455 (setter == null) ? null : kernel.elementToIr(setter));
456 }
457
458 Accessor computeAccessor(ForIn node, Element element) {
459 if (element == null) {
460 Send send = node.declaredIdentifier.asSend();
461 if (send == null) {
462 return buildStaticAccessor(null);
463 }
464 // This should be the situation where `node.declaredIdentifier` is
465 // unresolved, but in an instance method context. If it is some different
466 // situation, the assignment to [ir.PropertyGet] should act as an
467 // assertion.
468 ir.PropertyGet expression = visitForValue(send);
469 return PropertyAccessor.make(expression.receiver, expression.name);
470 } else if (kernel.isSyntheticError(element)) {
471 return buildStaticAccessor(null);
472 } else if (element.isGetter) {
473 if (element.isInstanceMember) {
474 return new ThisPropertyAccessor(kernel.irName(element.name, element));
475 } else {
476 GetterElement getter = element;
477 Element setter = getter.setter;
478 return buildStaticAccessor(getter, setter);
479 }
480 } else if (element.isLocal) {
481 return new VariableAccessor(getLocal(element));
482 } else if (element.isField) {
483 return buildStaticAccessor(element);
484 } else {
485 return buildStaticAccessor(null);
486 }
487 }
488
489 /// Builds a for-in statement for this case:
490 ///
491 /// for (element in expression) body
492 ///
493 /// This is normalized to:
494 ///
495 /// for (final #t in expression) {
496 /// element = #t;
497 /// body;
498 /// }
499 ir.Statement buildForInWithoutDeclaration(ForIn node, Element element,
500 {bool isAsync}) {
501 Accessor accessor = computeAccessor(node, elements.getForInVariable(node));
502 // Since we've created [variable], we know it's only assigned to in the
503 // loop header and can be final.
504 ir.VariableDeclaration variable =
505 new ir.VariableDeclaration.forValue(null, isFinal: true);
506 ir.Statement assigment = new ir.ExpressionStatement(accessor
507 .buildAssignment(new ir.VariableGet(variable), voidContext: true));
508 ir.Block body = buildStatementInBlock(node.body, forceBlock: true);
509 List<ir.Statement> statements = <ir.Statement>[assigment]
510 ..addAll(body.statements);
511 return buildForInCommon(node, variable, new ir.Block(statements),
512 isAsync: isAsync);
513 }
514
515 ir.Statement buildForIn(ForIn node, {bool isAsync}) {
516 VariableDefinitions declaration =
517 node.declaredIdentifier.asVariableDefinitions();
518 if (declaration != null) {
519 return buildForInWithDeclaration(node, declaration, isAsync: isAsync);
520 } else {
521 Element element = elements.getForInVariable(node);
522 return buildForInWithoutDeclaration(node, element, isAsync: isAsync);
523 }
524 }
525
526 @override
527 ir.Statement visitAsyncForIn(AsyncForIn node) {
528 return buildForIn(node, isAsync: true);
529 }
530
531 @override
532 ir.AwaitExpression visitAwait(Await node) {
533 return new ir.AwaitExpression(visitForValue(node.expression));
534 }
535
536 @override
537 ir.Statement visitBlock(Block node) {
538 return buildBreakTarget(
539 buildStatementInBlock(node), node, elements.getTargetDefinition(node));
540 }
541
542 bool buildStatement(Statement statement, List<ir.Statement> statements) {
543 ir.Node irNode = statement.accept(this);
544 bool hasVariableDeclaration = false;
545 if (irNode is VariableDeclarations) {
546 statements.addAll(irNode.variables);
547 hasVariableDeclaration = true;
548 } else {
549 statements.add(irNode);
550 if (irNode is ir.VariableDeclaration) {
551 hasVariableDeclaration = true;
552 }
553 }
554 return hasVariableDeclaration;
555 }
556
557 ir.Statement buildStatementInBlock(Statement node, {bool forceBlock: false}) {
558 if (node == null) return null;
559 List<ir.Statement> statements = <ir.Statement>[];
560 if (node is Block) {
561 for (Node statement in node.statements.nodes) {
562 buildStatement(statement, statements);
563 }
564 } else {
565 if (buildStatement(node, statements)) forceBlock = true;
566 if (!forceBlock && statements.length == 1) {
567 return statements.single;
568 }
569 // One VariableDefinitions statement node (dart2js AST) may generate
570 // multiple statements in Kernel IR so we sometimes fall through here.
571 }
572 return new ir.Block(statements);
573 }
574
575 @override
576 ir.Statement visitBreakStatement(BreakStatement node) {
577 JumpTarget target = elements.getTargetOf(node);
578 if (target == null || !target.statement.isValidBreakTarget()) {
579 // This is a break in an invalid position.
580 return new ir.InvalidStatement();
581 }
582 // A break can break to itself in the degenerate case `label: break
583 // label'`.
584 return buildBreakTarget(new ir.BreakStatement(getBreakTarget(target)), node,
585 elements.getTargetDefinition(node));
586 }
587
588 CascadeReceiver computeCascadeReceiver(Cascade cascade) {
589 CascadeReceiver receiver;
590 Expression send = cascade.expression.asSend();
591 while (send != null && (receiver = send.asCascadeReceiver()) == null) {
592 Expression possibleReceiver = send.asSend()?.receiver;
593 if (possibleReceiver != null) {
594 send = possibleReceiver;
595 } else {
596 // Can happen in this case: `a..add(foo)('WHAT')`.
597 send = send.asSend()?.selector;
598 }
599 }
600 if (receiver == null) {
601 internalError(cascade, "Can't find cascade receiver");
602 }
603 return receiver;
604 }
605
606 @override
607 ir.Let visitCascade(Cascade node) {
608 // Given this cascade expression `receiver..cascade1()..cascade2()`, the
609 // parser has produced a tree like this:
610 // Cascade(Send(
611 // CascadeReceiver(Cascade(Send(
612 // CascadeRecevier(receiver), 'cascade1', []))),
613 // 'cascade2', []))
614 // If viewed as a tree, `CascadeReceiver(receiver)` is the left-most leaf
615 // node. Below, we create this:
616 // cascades = [
617 // Cascade(Send(CascadeReceiver(...), 'cascade2', [])),
618 // Cascade(Send(CascadeReceiver(...), 'cascade1', []))]
619 // Notice that the cascades are in reverse order, which we use to build a
620 // `let` expression bottom up.
621 // First iteration of the loop produces:
622 // let dummy = rcv.cascade2() in
623 // rcv
624 // Second iteration:
625 // let dummy = rcv.cascade1() in
626 // let dummy = rcv.cascade2() in
627 // rcv
628 // Finally we return:
629 // let rcv = receiver in
630 // let dummy = rcv.cascade1() in
631 // let dummy = rcv.cascade2() in
632 // rcv
633 int startLength;
634 assert((startLength = cascadeReceivers.length) >= 0);
635
636 Cascade cascade = node;
637 List<Cascade> cascades = <Cascade>[];
638 CascadeReceiver receiver;
639 ir.VariableDeclaration receiverVariable = makeOrReuseVariable(null);
640
641 do {
642 cascades.add(cascade);
643 receiver = computeCascadeReceiver(cascade);
644 cascadeReceivers[receiver] = new ir.VariableGet(receiverVariable);
645 cascade = receiver.expression.asCascade();
646 } while (cascade != null);
647 // At this point, all nested [Cascades] targeting the same receiver have
648 // been collected in [cascades] in reverse order. [receiver] is the
649 // left-most receiver. [receiverVariable] will hold the value of evaluating
650 // [receiver]. Each [CascadeReceiver] has a getter for [receiverVariable]
651 // in [cascadeReceivers].
652
653 receiverVariable.initializer = visitForValue(receiver.expression);
654 receiverVariable.initializer.parent = receiverVariable;
655
656 ir.Expression result = new ir.VariableGet(receiverVariable); // rcv.
657 for (Cascade cascade in cascades) {
658 // When evaluating `cascade.expression`, we stop the recursion at
659 // [visitCascadeReceiver] and instead returns an [ir.VariableGet].
660 // TODO(ahe): Use visitForEffect here?
661 ir.Expression value = visitForValue(cascade.expression);
662 result = new ir.Let(makeOrReuseVariable(value), result);
663 }
664
665 assert(startLength == cascadeReceivers.length);
666 return new ir.Let(receiverVariable, result);
667 }
668
669 @override
670 ir.VariableGet visitCascadeReceiver(CascadeReceiver node) {
671 return cascadeReceivers.remove(node);
672 }
673
674 @override
675 visitCaseMatch(CaseMatch node) {
676 // Shouldn't be called. Handled by [visitSwitchCase].
677 return internalError(node, "CaseMatch");
678 }
679
680 @override
681 ir.Catch visitCatchBlock(CatchBlock node) {
682 ir.VariableDeclaration exception =
683 (node.exception == null) ? null : getLocal(elements[node.exception]);
684 ir.VariableDeclaration trace =
685 (node.trace == null) ? null : getLocal(elements[node.trace]);
686 ir.DartType guard = computeType(node.type);
687 return new ir.Catch(exception, buildStatementInBlock(node.block),
688 guard: guard, stackTrace: trace);
689 }
690
691 @override
692 ir.ConditionalExpression visitConditional(Conditional node) {
693 return new ir.ConditionalExpression(
694 visitForValue(node.condition),
695 visitWithCurrentContext(node.thenExpression),
696 visitWithCurrentContext(node.elseExpression));
697 }
698
699 @override
700 ir.Statement visitContinueStatement(ContinueStatement node) {
701 JumpTarget target = elements.getTargetOf(node);
702 if (target == null || !target.statement.isValidContinueTarget()) {
703 // This is a continue in an invalid position.
704 return new ir.InvalidStatement();
705 }
706 ir.SwitchCase switchCase = getContinueSwitchTarget(target);
707 return (switchCase == null)
708 ? new ir.BreakStatement(getContinueTarget(target))
709 : new ir.ContinueSwitchStatement(switchCase);
710 }
711
712 @override
713 ir.Statement visitDoWhile(DoWhile node) {
714 JumpTarget jumpTarget = elements.getTargetDefinition(node);
715 ir.Statement body =
716 buildContinueTarget(buildStatementInBlock(node.body), node, jumpTarget);
717 ir.Expression condition = visitForValue(node.condition);
718 return buildBreakTarget(
719 new ir.DoStatement(body, condition), node, jumpTarget);
720 }
721
722 @override
723 ir.EmptyStatement visitEmptyStatement(EmptyStatement node) {
724 return new ir.EmptyStatement();
725 }
726
727 @override
728 visitEnum(Enum node) {
729 // Not called normally. In dart2js, enums are represented as class
730 // elements, so `classToIr` handles enums. All the synthetic members of an
731 // enum class have already been installed by dart2js and we don't have to
732 // do anything special.
733 return internalError(node, "Enum");
734 }
735
736 @override
737 ir.ExpressionStatement visitExpressionStatement(ExpressionStatement node) {
738 return new ir.ExpressionStatement(visitForEffect(node.expression));
739 }
740
741 @override
742 ir.Statement visitFor(For node) {
743 VariableDefinitions initializers =
744 node.initializer?.asVariableDefinitions();
745 ir.Expression initializer;
746 List<ir.VariableDeclaration> variables;
747 if (initializers != null) {
748 ir.Block block = buildStatementInBlock(initializers, forceBlock: true);
749 variables = new List<ir.VariableDeclaration>.from(block.statements);
750 } else {
751 if (node.initializer != null) {
752 initializer = visitForValue(node.initializer);
753 }
754 variables = const <ir.VariableDeclaration>[];
755 }
756 ir.Expression condition = visitForValue(node.condition);
757 List<ir.Expression> updates = <ir.Expression>[];
758 for (Expression update in node.update) {
759 updates.add(visitForEffect(update));
760 }
761
762 JumpTarget jumpTarget = elements.getTargetDefinition(node);
763 ir.Statement body =
764 buildContinueTarget(buildStatementInBlock(node.body), node, jumpTarget);
765 ir.ForStatement forStatement =
766 new ir.ForStatement(variables, condition, updates, body);
767 ir.Statement result = buildBreakTarget(forStatement, node, jumpTarget);
768 if (initializer != null) {
769 result = new ir.Block(
770 <ir.Statement>[new ir.ExpressionStatement(initializer), result]);
771 }
772 return result;
773 }
774
775 @override
776 ir.FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) {
777 return node.function.accept(this);
778 }
779
780 @override
781 ir.Statement visitIf(If node) {
782 return buildBreakTarget(
783 new ir.IfStatement(
784 visitForValue(node.condition),
785 buildStatementInBlock(node.thenPart),
786 buildStatementInBlock(node.elsePart)),
787 node,
788 elements.getTargetDefinition(node));
789 }
790
791 @override
792 visitLabel(Label node) {
793 // Shouldn't be called. Handled by visitLabeledStatement and
794 // visitSwitchCase.
795 return internalError(node, "Label");
796 }
797
798 @override
799 ir.Statement visitLabeledStatement(LabeledStatement node) {
800 Statement statement = node.statement;
801 ir.Statement result = (statement is Block)
802 // If [statement] is a Block, we need to ensure that we don't bypass
803 // its visit method (so it can build break targets correctly).
804 ? statement.accept(this)
805 : buildStatementInBlock(statement);
806
807 // A [LabeledStatement] isn't the actual jump target, instead, [statement]
808 // is the target. This allows uniform handling of break and continue in
809 // loops. The following code simply assert that [result] has been generated
810 // correctly with respect to jump targets.
811 JumpTarget jumpTarget = elements.getTargetDefinition(node.statement);
812 if (jumpTarget != null) {
813 if (jumpTarget.isBreakTarget) {
814 ir.LabeledStatement target = breakTargets[jumpTarget];
815 if (target != null && target != result && target.parent == null) {
816 internalError(node, "no parent");
817 }
818 }
819 if (jumpTarget.isContinueTarget) {
820 ir.LabeledStatement target = continueTargets[jumpTarget];
821 if (target != null && target != result && target.parent == null) {
822 internalError(node, "no parent");
823 }
824 }
825 }
826
827 return result;
828 }
829
830 @override
831 ir.BoolLiteral visitLiteralBool(LiteralBool node) {
832 return new ir.BoolLiteral(node.value);
833 }
834
835 @override
836 ir.DoubleLiteral visitLiteralDouble(LiteralDouble node) {
837 return new ir.DoubleLiteral(node.value);
838 }
839
840 @override
841 ir.IntLiteral visitLiteralInt(LiteralInt node) {
842 return new ir.IntLiteral(node.value);
843 }
844
845 @override
846 ir.ListLiteral visitLiteralList(LiteralList node) {
847 // TODO(ahe): Type arguments.
848 List<ir.Expression> elements = <ir.Expression>[];
849 for (Expression element in node.elements.nodes) {
850 elements.add(visitForValue(element));
851 }
852 return new ir.ListLiteral(elements,
853 typeArgument: computeTypeFromTypes(node.typeArguments),
854 // TODO(ahe): Should constness be validated?
855 isConst: node.isConst);
856 }
857
858 @override
859 ir.MapLiteral visitLiteralMap(LiteralMap node) {
860 // TODO(ahe): Type arguments.
861 List<ir.MapEntry> entries = <ir.MapEntry>[];
862 for (LiteralMapEntry entry in node.entries.nodes) {
863 entries.add(new ir.MapEntry(
864 visitForValue(entry.key), visitForValue(entry.value)));
865 }
866 List<ir.DartType> typeArguments =
867 computeTypesFromTypes(node.typeArguments, expected: 2);
868 return new ir.MapLiteral(entries,
869 keyType: typeArguments.first,
870 valueType: typeArguments.last,
871 // TODO(ahe): Should Constness be validated?
872 isConst: node.isConst);
873 }
874
875 @override
876 visitLiteralMapEntry(LiteralMapEntry node) {
877 // Shouldn't be called. Handled by [visitLiteralMap].
878 return internalError(node, "LiteralMapEntry");
879 }
880
881 @override
882 ir.NullLiteral visitLiteralNull(LiteralNull node) {
883 return new ir.NullLiteral();
884 }
885
886 @override
887 ir.Expression visitLiteralString(LiteralString node) {
888 if (node.dartString == null) return new ir.InvalidExpression();
889 return new ir.StringLiteral(node.dartString.slowToString());
890 }
891
892 @override
893 ir.SymbolLiteral visitLiteralSymbol(LiteralSymbol node) {
894 return new ir.SymbolLiteral(node.slowNameString);
895 }
896
897 @override
898 visitMetadata(Metadata node) {
899 // Shouldn't be called. Metadata should already have been analyzed and
900 // converted to a constant expression in the resolver.
901 return internalError(node, "Metadata not handled as constant.");
902 }
903
904 @override
905 ir.NamedExpression visitNamedArgument(NamedArgument node) {
906 return new ir.NamedExpression(
907 node.name.source, visitForValue(node.expression));
908 }
909
910 @override
911 visitOperator(Operator node) {
912 // This is a special subclass of [Identifier], and we should never see that
913 // in the semantic visitor.
914 return internalError(node, "Operator");
915 }
916
917 @override
918 ir.Expression visitParenthesizedExpression(ParenthesizedExpression node) {
919 return visitWithCurrentContext(node.expression);
920 }
921
922 @override
923 ir.InvalidStatement visitRedirectingFactoryBody(RedirectingFactoryBody node) {
924 // Not implemented yet, only serves to recover from parser errors as
925 // dart2js is lenient in parsing something that looks like a redirecting
926 // factory method.
927 return new ir.InvalidStatement();
928 }
929
930 @override
931 ir.ExpressionStatement visitRethrow(Rethrow node) {
932 return new ir.ExpressionStatement(new ir.Rethrow());
933 }
934
935 @override
936 ir.ReturnStatement visitReturn(Return node) {
937 return new ir.ReturnStatement(visitForValue(node.expression));
938 }
939
940 @override
941 ir.StringConcatenation visitStringInterpolation(StringInterpolation node) {
942 List<ir.Expression> expressions = <ir.Expression>[];
943 expressions.add(visitForValue(node.string));
944 for (StringInterpolationPart part in node.parts) {
945 expressions.add(visitForValue(part.expression));
946 expressions.add(visitForValue(part.string));
947 }
948 return new ir.StringConcatenation(expressions);
949 }
950
951 @override
952 ir.StringConcatenation visitStringJuxtaposition(StringJuxtaposition node) {
953 return new ir.StringConcatenation(
954 <ir.Expression>[visitForValue(node.first), visitForValue(node.second)]);
955 }
956
957 @override
958 ir.SwitchCase visitSwitchCase(SwitchCase node) {
959 List<ir.Expression> expressions = <ir.Expression>[];
960 for (var labelOrCase in node.labelsAndCases.nodes) {
961 CaseMatch match = labelOrCase.asCaseMatch();
962 if (match != null) {
963 expressions.add(visitForValue(match.expression));
964 } else {
965 // Assert that labelOrCase is one of two known types: [CaseMatch] or
966 // [Label]. We ignore cases, as any users have been resolved to use the
967 // case directly.
968 assert(labelOrCase.asLabel() != null);
969 }
970 }
971 // We ignore the node's statements here, they're generated below in
972 // [visitSwitchStatement] once we've set up all the jump targets.
973 return new ir.SwitchCase(expressions, null, isDefault: node.isDefaultCase);
974 }
975
976 @override
977 ir.Statement visitSwitchStatement(SwitchStatement node) {
978 ir.Expression expression = visitForValue(node.expression);
979 List<ir.SwitchCase> cases = <ir.SwitchCase>[];
980 for (SwitchCase caseNode in node.cases.nodes) {
981 cases.add(caseNode.accept(this));
982 JumpTarget jumpTarget = elements.getTargetDefinition(caseNode);
983 if (jumpTarget != null) {
984 assert(jumpTarget.isContinueTarget);
985 assert(!continueSwitchTargets.containsKey(jumpTarget));
986 continueSwitchTargets[jumpTarget] = cases.last;
987 }
988 }
989
990 Iterator<ir.SwitchCase> casesIterator = cases.iterator;
991 for (Link<Node> link = node.cases.nodes;
992 link.isNotEmpty;
993 link = link.tail) {
994 SwitchCase caseNode = link.head;
995 bool isLastCase = link.tail.isEmpty;
996 if (!casesIterator.moveNext()) {
997 internalError(caseNode, "case node mismatch");
998 }
999 ir.SwitchCase irCase = casesIterator.current;
1000 List<ir.Statement> statements = <ir.Statement>[];
1001 bool hasVariableDeclaration = false;
1002 for (Statement statement in caseNode.statements.nodes) {
1003 if (buildStatement(statement, statements)) {
1004 hasVariableDeclaration = true;
1005 }
1006 }
1007 if (!isLastCase &&
1008 (statements.isEmpty || fallsThrough(statements.last))) {
1009 statements.add(new ir.ExpressionStatement(new ir.Throw(
1010 new ir.StaticInvocation(kernel.getFallThroughErrorBuilder(),
1011 new ir.Arguments.empty()))));
1012 }
1013 ir.Statement body;
1014 if (!hasVariableDeclaration && statements.length == 1) {
1015 body = statements.single;
1016 } else {
1017 body = new ir.Block(statements);
1018 }
1019 irCase.body = body;
1020 body.parent = irCase;
1021 }
1022 assert(!casesIterator.moveNext());
1023
1024 return buildBreakTarget(new ir.SwitchStatement(expression, cases), node,
1025 elements.getTargetDefinition(node));
1026 }
1027
1028 @override
1029 ir.Statement visitSyncForIn(SyncForIn node) {
1030 return buildForIn(node, isAsync: false);
1031 }
1032
1033 @override
1034 ir.Throw visitThrow(Throw node) {
1035 return new ir.Throw(visitForValue(node?.expression));
1036 }
1037
1038 @override
1039 ir.Statement visitTryStatement(TryStatement node) {
1040 ir.Statement result = buildStatementInBlock(node.tryBlock);
1041 if (node.catchBlocks != null && !node.catchBlocks.isEmpty) {
1042 List<ir.Catch> catchBlocks = <ir.Catch>[];
1043 for (CatchBlock block in node.catchBlocks.nodes) {
1044 catchBlocks.add(block.accept(this));
1045 }
1046 result = new ir.TryCatch(result, catchBlocks);
1047 }
1048 if (node.finallyBlock != null) {
1049 result =
1050 new ir.TryFinally(result, buildStatementInBlock(node.finallyBlock));
1051 }
1052 return buildBreakTarget(result, node, elements.getTargetDefinition(node));
1053 }
1054
1055 @override
1056 visitTypeAnnotation(TypeAnnotation node) {
1057 // Shouldn't be called, as the resolver have already resolved types and
1058 // created [DartType] objects.
1059 return internalError(node, "TypeAnnotation");
1060 }
1061
1062 @override
1063 visitTypeVariable(TypeVariable node) {
1064 // Shouldn't be called, as the resolver have already resolved types and
1065 // created [DartType] objects.
1066 return internalError(node, "TypeVariable");
1067 }
1068
1069 @override
1070 ir.Statement visitWhile(While node) {
1071 ir.Expression condition = visitForValue(node.condition);
1072 JumpTarget jumpTarget = elements.getTargetDefinition(node);
1073 ir.Statement body =
1074 buildContinueTarget(buildStatementInBlock(node.body), node, jumpTarget);
1075 return buildBreakTarget(
1076 new ir.WhileStatement(condition, body), node, jumpTarget);
1077 }
1078
1079 @override
1080 ir.YieldStatement visitYield(Yield node) {
1081 return new ir.YieldStatement(visitForValue(node.expression),
1082 isYieldStar: node.hasStar);
1083 }
1084
1085 @override
1086 ir.InvalidExpression visitAbstractClassConstructorInvoke(
1087 NewExpression node,
1088 ConstructorElement element,
1089 InterfaceType type,
1090 NodeList arguments,
1091 CallStructure callStructure,
1092 _) {
1093 return new ir.InvalidExpression();
1094 }
1095
1096 IrFunction buildIrFunction(
1097 ir.ProcedureKind kind, FunctionElement function, Node body) {
1098 return new IrFunction.procedure(kind, buildFunctionNode(function, body));
1099 }
1100
1101 @override
1102 IrFunction visitAbstractGetterDeclaration(
1103 FunctionExpression node, MethodElement getter, _) {
1104 return buildIrFunction(ir.ProcedureKind.Getter, getter, null);
1105 }
1106
1107 @override
1108 IrFunction visitAbstractSetterDeclaration(
1109 FunctionExpression node, MethodElement setter, NodeList parameters, _) {
1110 return buildIrFunction(ir.ProcedureKind.Setter, setter, null);
1111 }
1112
1113 @override
1114 ir.AsExpression visitAs(Send node, Node expression, DartType type, _) {
1115 return new ir.AsExpression(
1116 visitForValue(expression), kernel.typeToIr(type));
1117 }
1118
1119 @override
1120 ir.MethodInvocation visitBinary(
1121 Send node, Node left, BinaryOperator operator, Node right, _) {
1122 return buildBinaryOperator(left, operator.selectorName, right);
1123 }
1124
1125 ir.Expression buildConstructorInvoke(NewExpression node, {bool isConst}) {
1126 ConstructorElement constructor = elements[node.send];
1127 ConstructorTarget target =
1128 kernel.computeEffectiveTarget(constructor, elements.getType(node));
1129 NodeList arguments = node.send.argumentsNode;
1130 if (kernel.isSyntheticError(target.element)) {
1131 return new ir.MethodInvocation(new ir.InvalidExpression(),
1132 kernel.irName("call", currentElement), buildArguments(arguments));
1133 }
1134 ir.InvocationExpression invoke = target.element.isGenerativeConstructor
1135 ? buildGenerativeConstructorInvoke(target.element, arguments,
1136 isConst: isConst)
1137 : buildStaticInvoke(target.element, arguments, isConst: isConst);
1138 if (target.type.isInterfaceType) {
1139 InterfaceType type = target.type;
1140 if (type.isGeneric) {
1141 invoke.arguments.types.addAll(kernel.typesToIr(type.typeArguments));
1142 }
1143 }
1144 return invoke;
1145 }
1146
1147 @override
1148 ir.InvocationExpression visitBoolFromEnvironmentConstructorInvoke(
1149 NewExpression node, BoolFromEnvironmentConstantExpression constant, _) {
1150 return buildConstructorInvoke(node, isConst: true);
1151 }
1152
1153 ir.TypeLiteral buildTypeLiteral(TypeConstantExpression constant) {
1154 return new ir.TypeLiteral(kernel.typeLiteralToIr(constant));
1155 }
1156
1157 @override
1158 ir.TypeLiteral visitClassTypeLiteralGet(
1159 Send node, ConstantExpression constant, _) {
1160 return buildTypeLiteral(constant);
1161 }
1162
1163 @override
1164 ir.MethodInvocation visitClassTypeLiteralInvoke(
1165 Send node,
1166 ConstantExpression constant,
1167 NodeList arguments,
1168 CallStructure callStructure,
1169 _) {
1170 return buildCall(buildTypeLiteral(constant), callStructure, arguments);
1171 }
1172
1173 ir.Expression buildTypeLiteralSet(TypeConstantExpression constant, Node rhs) {
1174 return new ReadOnlyAccessor(buildTypeLiteral(constant))
1175 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
1176 }
1177
1178 @override
1179 ir.Expression visitClassTypeLiteralSet(
1180 SendSet node, ConstantExpression constant, Node rhs, _) {
1181 return buildTypeLiteralSet(constant, rhs);
1182 }
1183
1184 @override
1185 ir.FunctionExpression visitClosureDeclaration(FunctionExpression node,
1186 LocalFunctionElement closure, NodeList parameters, Node body, _) {
1187 return withCurrentElement(closure, () {
1188 return new ir.FunctionExpression(buildFunctionNode(closure, body));
1189 });
1190 }
1191
1192 @override
1193 ir.Expression visitCompoundIndexSet(SendSet node, Node receiver, Node index,
1194 AssignmentOperator operator, Node rhs, _) {
1195 return buildIndexAccessor(receiver, index).buildCompoundAssignment(
1196 kernel.irName(operator.selectorName, currentElement),
1197 visitForValue(rhs),
1198 voidContext: isVoidContext);
1199 }
1200
1201 @override
1202 ir.InvocationExpression visitConstConstructorInvoke(
1203 NewExpression node, ConstructedConstantExpression constant, _) {
1204 return buildConstructorInvoke(node, isConst: true);
1205 }
1206
1207 @override
1208 visitConstantGet(Send node, ConstantExpression constant, _) {
1209 // TODO(ahe): This method is never called. Is it a bug in semantic visitor?
1210 return internalError(node, "ConstantGet");
1211 }
1212
1213 @override
1214 visitConstantInvoke(Send node, ConstantExpression constant,
1215 NodeList arguments, CallStructure callStructure, _) {
1216 // TODO(ahe): This method is never called. Is it a bug in semantic visitor?
1217 return internalError(node, "ConstantInvoke");
1218 }
1219
1220 @override
1221 ir.InvalidExpression visitConstructorIncompatibleInvoke(
1222 NewExpression node,
1223 ConstructorElement constructor,
1224 InterfaceType type,
1225 NodeList arguments,
1226 CallStructure callStructure,
1227 _) {
1228 return new ir.InvalidExpression();
1229 }
1230
1231 @override
1232 ir.PropertyGet visitDynamicPropertyGet(
1233 Send node, Node receiver, Name name, _) {
1234 return new ir.PropertyGet(visitForValue(receiver), nameToIrName(name));
1235 }
1236
1237 @override
1238 ir.MethodInvocation visitDynamicPropertyInvoke(
1239 Send node, Node receiver, NodeList arguments, Selector selector, _) {
1240 return buildInvokeSelector(
1241 visitForValue(receiver), selector, buildArguments(arguments));
1242 }
1243
1244 @override
1245 ir.Expression handleDynamicCompounds(
1246 Send node, Node receiver, Name name, CompoundRhs rhs, _) {
1247 ir.Expression receiverNode =
1248 receiver == null ? new ir.ThisExpression() : visitForValue(receiver);
1249 return buildCompound(
1250 PropertyAccessor.make(receiverNode, nameToIrName(name)), rhs);
1251 }
1252
1253 @override
1254 ir.PropertySet visitDynamicPropertySet(
1255 SendSet node, Node receiver, Name name, Node rhs, _) {
1256 ir.Expression value = visitForValue(rhs);
1257 return new ir.PropertySet(
1258 visitForValue(receiver), nameToIrName(name), value);
1259 }
1260
1261 @override
1262 ir.Expression handleDynamicSetIfNulls(
1263 Send node, Node receiver, Name name, Node rhs, _) {
1264 ir.Name irName = nameToIrName(name);
1265 Accessor accessor = (receiver == null)
1266 ? new ThisPropertyAccessor(irName)
1267 : PropertyAccessor.make(visitForValue(receiver), irName);
1268 return accessor.buildNullAwareAssignment(visitForValue(rhs),
1269 voidContext: isVoidContext);
1270 }
1271
1272 @override
1273 ir.TypeLiteral visitDynamicTypeLiteralGet(
1274 Send node, ConstantExpression constant, _) {
1275 return buildTypeLiteral(constant);
1276 }
1277
1278 @override
1279 ir.MethodInvocation visitDynamicTypeLiteralInvoke(
1280 Send node,
1281 ConstantExpression constant,
1282 NodeList arguments,
1283 CallStructure callStructure,
1284 _) {
1285 return buildCall(buildTypeLiteral(constant), callStructure, arguments);
1286 }
1287
1288 @override
1289 ir.Expression visitDynamicTypeLiteralSet(
1290 SendSet node, ConstantExpression constant, Node rhs, _) {
1291 return buildTypeLiteralSet(constant, rhs);
1292 }
1293
1294 ir.MethodInvocation buildBinaryOperator(
1295 Node left, String operator, Node right) {
1296 ir.Name name = kernel.irName(operator, currentElement);
1297 return makeBinary(visitForValue(left), name, visitForValue(right));
1298 }
1299
1300 @override
1301 ir.MethodInvocation visitEquals(Send node, Node left, Node right, _) {
1302 return buildBinaryOperator(left, '==', right);
1303 }
1304
1305 @override
1306 ir.MethodInvocation visitExpressionInvoke(Send node, Node expression,
1307 NodeList arguments, CallStructure callStructure, _) {
1308 return buildCall(visitForValue(expression), callStructure, arguments);
1309 }
1310
1311 @override
1312 IrFunction visitFactoryConstructorDeclaration(FunctionExpression node,
1313 ConstructorElement constructor, NodeList parameters, Node body, _) {
1314 return buildIrFunction(ir.ProcedureKind.Factory, constructor, body);
1315 }
1316
1317 @override
1318 ir.InvocationExpression visitFactoryConstructorInvoke(
1319 NewExpression node,
1320 ConstructorElement constructor,
1321 InterfaceType type,
1322 NodeList arguments,
1323 CallStructure callStructure,
1324 _) {
1325 return buildConstructorInvoke(node, isConst: false);
1326 }
1327
1328 @override
1329 ir.Initializer visitFieldInitializer(
1330 SendSet node, FieldElement field, Node expression, _) {
1331 if (kernel.isSyntheticError(field)) {
1332 return new ir.InvalidInitializer();
1333 } else {
1334 return new ir.FieldInitializer(
1335 kernel.fieldToIr(field), visitForValue(expression));
1336 }
1337 }
1338
1339 ir.Expression buildStaticFieldSet(FieldElement field, Node rhs) {
1340 return buildStaticAccessor(field)
1341 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
1342 }
1343
1344 @override
1345 ir.Expression handleFinalStaticFieldSet(
1346 SendSet node, FieldElement field, Node rhs, _) {
1347 return buildStaticFieldSet(field, rhs);
1348 }
1349
1350 @override
1351 ir.Expression visitFinalSuperFieldSet(
1352 SendSet node, FieldElement field, Node rhs, _) {
1353 return buildSuperPropertyAccessor(field)
1354 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
1355 }
1356
1357 void addFieldsWithInitializers(
1358 ConstructorElement constructor, List<ir.Initializer> initializers) {
1359 constructor.enclosingClass.forEachInstanceField((_, FieldElement element) {
1360 // Convert the element into the corresponding IR field before asking
1361 // if the initializer exists. This is necessary to ensure that the
1362 // element has been analyzed before looking at its initializer.
1363 ir.Field field = kernel.fieldToIr(element);
1364 if (element.initializer != null) {
1365 KernelVisitor visitor =
1366 new KernelVisitor(element, element.treeElements, kernel);
1367 ir.Expression value = visitor.buildInitializer();
1368 initializers.add(new ir.FieldInitializer(field, value));
1369 }
1370 });
1371 }
1372
1373 IrFunction buildGenerativeConstructor(
1374 ConstructorElement constructor, NodeList parameters, Node body) {
1375 List<ir.Initializer> constructorInitializers = <ir.Initializer>[];
1376 if (kernel.hasHierarchyProblem(constructor.enclosingClass)) {
1377 constructorInitializers.add(new ir.InvalidInitializer());
1378 } else if (constructor.isSynthesized) {
1379 List<ir.Expression> arguments = const <ir.Expression>[];
1380 List<ir.NamedExpression> named = const <ir.NamedExpression>[];
1381 FunctionSignature signature = constructor.functionSignature;
1382 if (signature.parameterCount != 0) {
1383 // Mixin application implicit super call.
1384 arguments = <ir.Expression>[];
1385 named = <ir.NamedExpression>[];
1386 signature.orderedForEachParameter((ParameterElement parameter) {
1387 ir.VariableGet argument = buildLocalGet(parameter);
1388 if (parameter.isNamed) {
1389 named.add(new ir.NamedExpression(parameter.name, argument));
1390 } else {
1391 arguments.add(argument);
1392 }
1393 });
1394 }
1395 if (kernel.isSyntheticError(constructor.definingConstructor)) {
1396 constructorInitializers.add(new ir.InvalidInitializer());
1397 } else {
1398 addFieldsWithInitializers(constructor, constructorInitializers);
1399 constructorInitializers.add(new ir.SuperInitializer(
1400 kernel.functionToIr(constructor.definingConstructor),
1401 new ir.Arguments(arguments, named: named, types: null)));
1402 }
1403 } else {
1404 addFieldsWithInitializers(constructor, constructorInitializers);
1405 if (parameters != null) {
1406 // TODO(ahe): the following is a (modified) copy of
1407 // [SemanticDeclarationResolvedMixin.visitParameters].
1408 List<ParameterStructure> structures =
1409 computeParameterStructures(parameters);
1410 for (ParameterStructure structure in structures) {
1411 if (structure.parameter.isInitializingFormal) {
1412 constructorInitializers.add(structure.dispatch(declVisitor, null));
1413 }
1414 }
1415 }
1416 // TODO(ahe): the following is a (modified) copy of
1417 // [SemanticDeclarationResolvedMixin.visitInitializers].
1418 InitializersStructure initializers =
1419 computeInitializersStructure(constructor.node);
1420 for (InitializerStructure structure in initializers.initializers) {
1421 constructorInitializers.add(structure.dispatch(declVisitor, null));
1422 }
1423 }
1424 return new IrFunction.constructor(
1425 buildFunctionNode(constructor, body), constructorInitializers);
1426 }
1427
1428 @override
1429 IrFunction visitGenerativeConstructorDeclaration(
1430 FunctionExpression node,
1431 ConstructorElement constructor,
1432 NodeList parameters,
1433 NodeList initializers,
1434 Node body,
1435 _) {
1436 return buildGenerativeConstructor(constructor, parameters, body);
1437 }
1438
1439 ir.ConstructorInvocation buildGenerativeConstructorInvoke(
1440 ConstructorElement constructor, NodeList arguments,
1441 {bool isConst}) {
1442 if (const bool.fromEnvironment("require_kernel_arguments")) {
1443 // Check that all constructors from kernel/ast.dart (that are invoked
1444 // from this package) provide all arguments (including optional
1445 // arguments).
1446 // TODO(ahe): Remove this when the implementation has matured.
1447 if (("package:kernel/ast.dart" ==
1448 "${constructor.library.canonicalUri}") &&
1449 "${currentElement.library.canonicalUri}"
1450 .startsWith("package:rasta/")) {
1451 if (constructor.functionSignature.parameterCount !=
1452 arguments.slowLength()) {
1453 kernel.debugMessage(arguments, "Missing arguments");
1454 kernel.debugMessage(constructor, "When calling the constructor");
1455 }
1456 }
1457 }
1458 ir.Arguments argumentsNode = buildArguments(arguments);
1459 ir.Constructor target = kernel.functionToIr(constructor);
1460 return new ir.ConstructorInvocation(target, argumentsNode,
1461 isConst: isConst);
1462 }
1463
1464 @override
1465 ir.InvocationExpression visitGenerativeConstructorInvoke(
1466 NewExpression node,
1467 ConstructorElement constructor,
1468 InterfaceType type,
1469 NodeList arguments,
1470 CallStructure callStructure,
1471 _) {
1472 return buildConstructorInvoke(node, isConst: false);
1473 }
1474
1475 Accessor buildNullAwarePropertyAccessor(Node receiver, Name name) {
1476 return new NullAwarePropertyAccessor(
1477 visitForValue(receiver), nameToIrName(name));
1478 }
1479
1480 @override
1481 ir.Expression visitIfNotNullDynamicPropertyGet(
1482 Send node, Node receiver, Name name, _) {
1483 return buildNullAwarePropertyAccessor(receiver, name).buildSimpleRead();
1484 }
1485
1486 @override
1487 ir.Let visitIfNotNullDynamicPropertyInvoke(
1488 Send node, Node receiverNode, NodeList arguments, Selector selector, _) {
1489 ir.VariableDeclaration receiver =
1490 makeOrReuseVariable(visitForValue(receiverNode));
1491 return makeLet(
1492 receiver,
1493 new ir.ConditionalExpression(
1494 buildIsNull(new ir.VariableGet(receiver)),
1495 new ir.NullLiteral(),
1496 buildInvokeSelector(new ir.VariableGet(receiver), selector,
1497 buildArguments(arguments))));
1498 }
1499
1500 @override
1501 ir.Expression visitIfNotNullDynamicPropertySet(
1502 SendSet node, Node receiver, Name name, Node rhs, _) {
1503 return buildNullAwarePropertyAccessor(receiver, name)
1504 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
1505 }
1506
1507 @override
1508 ir.Expression visitIfNotNullDynamicPropertySetIfNull(
1509 Send node, Node receiver, Name name, Node rhs, _) {
1510 return buildNullAwarePropertyAccessor(receiver, name)
1511 .buildNullAwareAssignment(visitForValue(rhs),
1512 voidContext: isVoidContext);
1513 }
1514
1515 ir.LogicalExpression buildLogicalExpression(
1516 Node left, Operator operator, Node right) {
1517 return new ir.LogicalExpression(
1518 visitForValue(left), operator.source, visitForValue(right));
1519 }
1520
1521 @override
1522 ir.LogicalExpression visitIfNull(Send node, Node left, Node right, _) {
1523 return buildLogicalExpression(left, node.selector, right);
1524 }
1525
1526 @override
1527 ir.Initializer visitImplicitSuperConstructorInvoke(FunctionExpression node,
1528 ConstructorElement superConstructor, InterfaceType type, _) {
1529 if (superConstructor == null) {
1530 // TODO(ahe): Semantic visitor shouldn't call this.
1531 return new ir.InvalidInitializer();
1532 }
1533 return new ir.SuperInitializer(
1534 kernel.functionToIr(superConstructor), new ir.Arguments.empty());
1535 }
1536
1537 Accessor buildIndexAccessor(Node receiver, Node index) {
1538 return IndexAccessor.make(visitForValue(receiver), visitForValue(index));
1539 }
1540
1541 @override
1542 ir.Expression visitIndex(Send node, Node receiver, Node index, _) {
1543 return buildIndexAccessor(receiver, index).buildSimpleRead();
1544 }
1545
1546 ir.Expression buildIndexPostfix(Accessor accessor, IncDecOperator operator) {
1547 ir.Name name = kernel.irName(operator.selectorName, currentElement);
1548 return accessor.buildPostfixIncrement(name, voidContext: isVoidContext);
1549 }
1550
1551 @override
1552 ir.Expression visitIndexPostfix(
1553 Send node, Node receiver, Node index, IncDecOperator operator, _) {
1554 return buildIndexPostfix(buildIndexAccessor(receiver, index), operator);
1555 }
1556
1557 ir.Expression buildIndexPrefix(Accessor accessor, IncDecOperator operator) {
1558 ir.Name name = kernel.irName(operator.selectorName, currentElement);
1559 return accessor.buildPrefixIncrement(name, voidContext: isVoidContext);
1560 }
1561
1562 @override
1563 ir.Expression visitIndexPrefix(
1564 Send node, Node receiver, Node index, IncDecOperator operator, _) {
1565 return buildIndexPrefix(buildIndexAccessor(receiver, index), operator);
1566 }
1567
1568 @override
1569 ir.Expression visitIndexSet(
1570 SendSet node, Node receiver, Node index, Node rhs, _) {
1571 return buildIndexAccessor(receiver, index)
1572 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
1573 }
1574
1575 ir.Initializer buildInitializingFormal(InitializingFormalElement parameter) {
1576 FieldElement field = parameter.fieldElement;
1577 if (kernel.isSyntheticError(field)) {
1578 return new ir.InvalidInitializer();
1579 } else {
1580 return new ir.FieldInitializer(
1581 kernel.fieldToIr(field), buildLocalGet(parameter));
1582 }
1583 }
1584
1585 @override
1586 ir.Initializer visitInitializingFormalDeclaration(VariableDefinitions node,
1587 Node definition, InitializingFormalElement parameter, int index, _) {
1588 return buildInitializingFormal(parameter);
1589 }
1590
1591 @override
1592 visitInstanceFieldDeclaration(VariableDefinitions node, Node definition,
1593 FieldElement field, Node initializer, _) {
1594 // Shouldn't be called, handled by fieldToIr.
1595 return internalError(node, "InstanceFieldDeclaration");
1596 }
1597
1598 @override
1599 IrFunction visitInstanceGetterDeclaration(
1600 FunctionExpression node, MethodElement getter, Node body, _) {
1601 return buildIrFunction(ir.ProcedureKind.Getter, getter, body);
1602 }
1603
1604 @override
1605 IrFunction visitInstanceSetterDeclaration(FunctionExpression node,
1606 MethodElement setter, NodeList parameters, Node body, _) {
1607 return buildIrFunction(ir.ProcedureKind.Setter, setter, body);
1608 }
1609
1610 @override
1611 ir.InvocationExpression visitIntFromEnvironmentConstructorInvoke(
1612 NewExpression node, IntFromEnvironmentConstantExpression constant, _) {
1613 return buildConstructorInvoke(node, isConst: true);
1614 }
1615
1616 ir.IsExpression buildIs(Node expression, DartType type) {
1617 return new ir.IsExpression(
1618 visitForValue(expression), kernel.typeToIr(type));
1619 }
1620
1621 @override
1622 ir.IsExpression visitIs(Send node, Node expression, DartType type, _) {
1623 return buildIs(expression, type);
1624 }
1625
1626 @override
1627 ir.Not visitIsNot(Send node, Node expression, DartType type, _) {
1628 return new ir.Not(buildIs(expression, type));
1629 }
1630
1631 ir.VariableDeclaration buildLocalVariableDeclaration(
1632 LocalVariableElement variable, Node initializer) {
1633 ir.Expression initializerNode = visitForValue(initializer);
1634 ir.VariableDeclaration local = getLocal(variable);
1635 if (initializer != null) {
1636 local.initializer = initializerNode;
1637 initializerNode.parent = local;
1638 }
1639 return local;
1640 }
1641
1642 @override
1643 ir.VariableDeclaration visitLocalConstantDeclaration(
1644 VariableDefinitions node,
1645 Node definition,
1646 LocalVariableElement variable,
1647 ConstantExpression constant,
1648 _) {
1649 // TODO(ahe): Use [constant]?
1650 return buildLocalVariableDeclaration(variable, variable.initializer)
1651 ..isConst = true;
1652 }
1653
1654 @override
1655 ir.FunctionDeclaration visitLocalFunctionDeclaration(FunctionExpression node,
1656 LocalFunctionElement localFunction, NodeList parameters, Node body, _) {
1657 return withCurrentElement(localFunction, () {
1658 ir.VariableDeclaration local = getLocal(localFunction)..isFinal = true;
1659 return new ir.FunctionDeclaration(
1660 local, buildFunctionNode(localFunction, body));
1661 });
1662 }
1663
1664 @override
1665 ir.VariableDeclaration visitLocalVariableDeclaration(VariableDefinitions node,
1666 Node definition, LocalVariableElement variable, Node initializer, _) {
1667 return buildLocalVariableDeclaration(variable, initializer);
1668 }
1669
1670 ir.VariableGet buildLocalGet(LocalElement local) {
1671 return new ir.VariableGet(getLocal(local));
1672 }
1673
1674 @override
1675 ir.VariableGet handleLocalGet(Send node, LocalElement element, _) {
1676 return buildLocalGet(element);
1677 }
1678
1679 ir.Expression buildCompound(Accessor accessor, CompoundRhs rhs) {
1680 ir.Name name = kernel.irName(rhs.operator.selectorName, currentElement);
1681 switch (rhs.kind) {
1682 case CompoundKind.POSTFIX:
1683 return accessor.buildPostfixIncrement(name, voidContext: isVoidContext);
1684
1685 case CompoundKind.PREFIX:
1686 return accessor.buildPrefixIncrement(name, voidContext: isVoidContext);
1687
1688 case CompoundKind.ASSIGNMENT:
1689 return accessor.buildCompoundAssignment(name, visitForValue(rhs.rhs),
1690 voidContext: isVoidContext);
1691 }
1692 }
1693
1694 @override
1695 ir.Expression handleLocalCompounds(
1696 SendSet node, LocalElement local, CompoundRhs rhs, _,
1697 {bool isSetterValid}) {
1698 return buildCompound(new VariableAccessor(getLocal(local)), rhs);
1699 }
1700
1701 @override
1702 ir.VariableSet handleLocalSet(
1703 SendSet node, LocalElement element, Node rhs, _) {
1704 return new ir.VariableSet(getLocal(element), visitForValue(rhs));
1705 }
1706
1707 @override
1708 ir.VariableSet handleImmutableLocalSet(
1709 SendSet node, LocalElement element, Node rhs, _) {
1710 // TODO(ahe): Build invalid?
1711 return handleLocalSet(node, element, rhs, _);
1712 }
1713
1714 @override
1715 ir.LogicalExpression visitLogicalAnd(Send node, Node left, Node right, _) {
1716 return buildLogicalExpression(left, node.selector, right);
1717 }
1718
1719 @override
1720 ir.LogicalExpression visitLogicalOr(Send node, Node left, Node right, _) {
1721 return buildLogicalExpression(left, node.selector, right);
1722 }
1723
1724 @override
1725 ir.Initializer visitNamedInitializingFormalDeclaration(
1726 VariableDefinitions node,
1727 Node definition,
1728 InitializingFormalElement parameter,
1729 ConstantExpression defaultValue,
1730 _) {
1731 return buildInitializingFormal(parameter);
1732 }
1733
1734 @override
1735 visitNamedParameterDeclaration(VariableDefinitions node, Node definition,
1736 ParameterElement parameter, ConstantExpression defaultValue, _) {
1737 // Shouldn't be called, we handle parameters via [FunctionSignture].
1738 return internalError(node, "NamedParameterDeclaration");
1739 }
1740
1741 @override
1742 ir.Not visitNot(Send node, Node expression, _) {
1743 return new ir.Not(visitForValue(expression));
1744 }
1745
1746 @override
1747 ir.Not visitNotEquals(Send node, Node left, Node right, _) {
1748 return new ir.Not(buildBinaryOperator(left, '==', right));
1749 }
1750
1751 @override
1752 ir.Initializer visitOptionalInitializingFormalDeclaration(
1753 VariableDefinitions node,
1754 Node definition,
1755 InitializingFormalElement parameter,
1756 ConstantExpression defaultValue,
1757 int index,
1758 _) {
1759 return buildInitializingFormal(parameter);
1760 }
1761
1762 @override
1763 visitOptionalParameterDeclaration(
1764 VariableDefinitions node,
1765 Node definition,
1766 ParameterElement parameter,
1767 ConstantExpression defaultValue,
1768 int index,
1769 _) {
1770 // Shouldn't be called, we handle parameters via [FunctionSignture].
1771 return internalError(node, "OptionalParameterDeclaration");
1772 }
1773
1774 @override
1775 visitParameterDeclaration(VariableDefinitions node, Node definition,
1776 ParameterElement parameter, int index, _) {
1777 // Shouldn't be called, we handle parameters via [FunctionSignture].
1778 return internalError(node, "ParameterDeclaration");
1779 }
1780
1781 @override
1782 ir.MethodInvocation handleLocalInvoke(Send node, LocalElement element,
1783 NodeList arguments, CallStructure callStructure, _) {
1784 return buildCall(buildLocalGet(element), callStructure, arguments);
1785 }
1786
1787 @override
1788 ir.Expression handleLocalSetIfNulls(
1789 SendSet node, LocalElement local, Node rhs, _,
1790 {bool isSetterValid}) {
1791 return new VariableAccessor(getLocal(local)).buildNullAwareAssignment(
1792 visitForValue(rhs),
1793 voidContext: isVoidContext);
1794 }
1795
1796 @override
1797 IrFunction visitRedirectingFactoryConstructorDeclaration(
1798 FunctionExpression node,
1799 ConstructorElement constructor,
1800 NodeList parameters,
1801 DartType redirectionType, // TODO(ahe): Should be InterfaceType.
1802 ConstructorElement redirectionTarget,
1803 _) {
1804 if (!constructor.isFactoryConstructor) {
1805 // TODO(ahe): This seems like a bug in semantic visitor and how it
1806 // recovers from a bad constructor.
1807 return new IrFunction.constructor(buildFunctionNode(constructor, null),
1808 <ir.Initializer>[new ir.InvalidInitializer()]);
1809 }
1810 ir.Statement body = null;
1811 if (kernel.isSyntheticError(redirectionTarget)) {
1812 body = new ir.InvalidStatement();
1813 } else {
1814 // TODO(ahe): This should be implemented, but doesn't matter much unless
1815 // we support reflection. At the call-site, we bypass this factory and
1816 // call its effective target directly. So this factory is only necessary
1817 // for reflection.
1818 body = new ir.InvalidStatement();
1819 }
1820 IrFunction function =
1821 buildIrFunction(ir.ProcedureKind.Factory, constructor, null);
1822 function.node.body = body..parent = function.node;
1823 return function;
1824 }
1825
1826 @override
1827 ir.InvocationExpression visitRedirectingFactoryConstructorInvoke(
1828 NewExpression node,
1829 ConstructorElement constructor,
1830 InterfaceType type,
1831 ConstructorElement effectiveTarget,
1832 InterfaceType effectiveTargetType,
1833 NodeList arguments,
1834 CallStructure callStructure,
1835 _) {
1836 return buildConstructorInvoke(node, isConst: false);
1837 }
1838
1839 @override
1840 IrFunction visitRedirectingGenerativeConstructorDeclaration(
1841 FunctionExpression node,
1842 ConstructorElement constructor,
1843 NodeList parameters,
1844 NodeList initializers,
1845 _) {
1846 return buildGenerativeConstructor(constructor, parameters, null);
1847 }
1848
1849 @override
1850 ir.InvocationExpression visitRedirectingGenerativeConstructorInvoke(
1851 NewExpression node,
1852 ConstructorElement constructor,
1853 InterfaceType type,
1854 NodeList arguments,
1855 CallStructure callStructure,
1856 _) {
1857 return buildConstructorInvoke(node, isConst: false);
1858 }
1859
1860 @override
1861 visitStaticConstantDeclaration(VariableDefinitions node, Node definition,
1862 FieldElement field, ConstantExpression constant, _) {
1863 // Shouldn't be called, handled by fieldToIr.
1864 return internalError(node, "StaticConstantDeclaration");
1865 }
1866
1867 @override
1868 visitStaticFieldDeclaration(VariableDefinitions node, Node definition,
1869 FieldElement field, Node initializer, _) {
1870 // Shouldn't be called, handled by fieldToIr.
1871 return internalError(node, "StaticFieldDeclaration");
1872 }
1873
1874 ir.Expression buildStaticGet(Element element) {
1875 return buildStaticAccessor(element).buildSimpleRead();
1876 }
1877
1878 @override
1879 ir.Expression handleStaticFieldGet(Send node, FieldElement field, _) {
1880 return buildStaticGet(field);
1881 }
1882
1883 @override
1884 ir.MethodInvocation handleStaticFieldInvoke(Send node, FieldElement field,
1885 NodeList arguments, CallStructure callStructure, _) {
1886 return buildCall(buildStaticGet(field), callStructure, arguments);
1887 }
1888
1889 @override
1890 ir.Expression handleStaticFieldSet(
1891 SendSet node, FieldElement field, Node rhs, _) {
1892 return buildStaticFieldSet(field, rhs);
1893 }
1894
1895 @override
1896 ir.Expression handleStaticSetIfNulls(
1897 SendSet node,
1898 Element getter,
1899 CompoundGetter getterKind,
1900 Element setter,
1901 CompoundSetter setterKind,
1902 Node rhs,
1903 _) {
1904 if (setterKind == CompoundSetter.INVALID) {
1905 setter = null;
1906 }
1907 return buildStaticAccessor(getter, setter).buildNullAwareAssignment(
1908 visitForValue(rhs),
1909 voidContext: isVoidContext);
1910 }
1911
1912 ir.VariableDeclaration getLocal(LocalElement local) {
1913 return locals.putIfAbsent(local, () {
1914 return new ir.VariableDeclaration(local.name,
1915 initializer: null,
1916 type: typeToIrHack(local.type),
1917 isFinal: local.isFinal,
1918 isConst: local.isConst);
1919 });
1920 }
1921
1922 ir.FunctionNode buildFunctionNode(FunctionElement function, Node bodyNode) {
1923 List<ir.TypeParameter> typeParameters =
1924 kernel.typeParametersNotImplemented();
1925 List<ir.VariableDeclaration> positionalParameters =
1926 <ir.VariableDeclaration>[];
1927 List<ir.VariableDeclaration> namedParameters = <ir.VariableDeclaration>[];
1928 int requiredParameterCount = 0;
1929 ir.DartType returnType = const ir.DynamicType();
1930 if (function.hasFunctionSignature) {
1931 FunctionSignature signature = function.functionSignature;
1932 requiredParameterCount = signature.requiredParameterCount;
1933 signature.forEachParameter((ParameterElement parameter) {
1934 ir.VariableDeclaration variable = getLocal(parameter);
1935 if (parameter.isNamed) {
1936 namedParameters.add(variable);
1937 } else {
1938 positionalParameters.add(variable);
1939 }
1940 });
1941 signature.forEachParameter((ParameterElement parameter) {
1942 if (!parameter.isOptional) return;
1943 ir.Expression initializer = visitForValue(parameter.initializer);
1944 ir.VariableDeclaration variable = getLocal(parameter);
1945 if (initializer != null) {
1946 variable.initializer = initializer;
1947 initializer.parent = variable;
1948 }
1949 });
1950 returnType = typeToIrHack(signature.type.returnType);
1951 if (function.isFactoryConstructor) {
1952 InterfaceType type = function.enclosingClass.thisType;
1953 if (type.isGeneric) {
1954 typeParameters = new List<ir.TypeParameter>();
1955 for (DartType parameter in type.typeArguments) {
1956 typeParameters.add(kernel.typeVariableToIr(parameter.element));
1957 }
1958 }
1959 }
1960 }
1961 ir.AsyncMarker asyncMarker = ir.AsyncMarker.Sync;
1962 if (!kernel.isSyntheticError(function)) {
1963 switch (function.asyncMarker) {
1964 case AsyncMarker.SYNC:
1965 asyncMarker = ir.AsyncMarker.Sync;
1966 break;
1967
1968 case AsyncMarker.SYNC_STAR:
1969 asyncMarker = ir.AsyncMarker.SyncStar;
1970 break;
1971
1972 case AsyncMarker.ASYNC:
1973 asyncMarker = ir.AsyncMarker.Async;
1974 break;
1975
1976 case AsyncMarker.ASYNC_STAR:
1977 asyncMarker = ir.AsyncMarker.AsyncStar;
1978 break;
1979
1980 default:
1981 internalError(
1982 function, "Unknown async maker: ${function.asyncMarker}");
1983 break;
1984 }
1985 }
1986 ir.Statement body =
1987 (bodyNode == null) ? null : buildStatementInBlock(bodyNode);
1988 return new ir.FunctionNode(body,
1989 asyncMarker: asyncMarker,
1990 returnType: returnType,
1991 typeParameters: typeParameters,
1992 positionalParameters: positionalParameters,
1993 namedParameters: namedParameters,
1994 requiredParameterCount: requiredParameterCount);
1995 }
1996
1997 @override
1998 IrFunction visitStaticFunctionDeclaration(FunctionExpression node,
1999 MethodElement function, NodeList parameters, Node body, _) {
2000 return buildIrFunction(ir.ProcedureKind.Method, function, body);
2001 }
2002
2003 ir.ProcedureKind computeInstanceMethodKind(MethodElement method) {
2004 assert(method.isFunction);
2005 return method.isOperator
2006 ? ir.ProcedureKind.Operator
2007 : ir.ProcedureKind.Method;
2008 }
2009
2010 @override
2011 IrFunction visitInstanceMethodDeclaration(FunctionExpression node,
2012 MethodElement method, NodeList parameters, Node body, _) {
2013 return buildIrFunction(
2014 computeInstanceMethodKind(currentElement), currentElement, body);
2015 }
2016
2017 @override
2018 IrFunction visitAbstractMethodDeclaration(
2019 FunctionExpression node, MethodElement method, NodeList parameters, _) {
2020 return buildIrFunction(
2021 computeInstanceMethodKind(currentElement), currentElement, null);
2022 }
2023
2024 @override
2025 ir.Expression handleStaticFunctionGet(Send node, MethodElement function, _) {
2026 return buildStaticGet(function);
2027 }
2028
2029 @override
2030 ir.StaticInvocation handleStaticFunctionIncompatibleInvoke(
2031 Send node,
2032 MethodElement function,
2033 NodeList arguments,
2034 CallStructure callStructure,
2035 _) {
2036 return buildStaticInvoke(function, arguments, isConst: false);
2037 }
2038
2039 ir.StaticInvocation buildStaticInvoke(
2040 FunctionElement function, NodeList arguments,
2041 {bool isConst}) {
2042 ir.Arguments argumentsNode = buildArguments(arguments);
2043 return new ir.StaticInvocation(kernel.functionToIr(function), argumentsNode,
2044 isConst: isConst);
2045 }
2046
2047 @override
2048 ir.StaticInvocation handleStaticFunctionInvoke(
2049 Send node,
2050 MethodElement function,
2051 NodeList arguments,
2052 CallStructure callStructure,
2053 _) {
2054 return buildStaticInvoke(function, arguments, isConst: false);
2055 }
2056
2057 @override
2058 ir.Expression handleStaticFunctionSet(
2059 Send node, MethodElement function, Node rhs, _) {
2060 return buildStaticAccessor(function)
2061 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2062 }
2063
2064 @override
2065 IrFunction visitStaticGetterDeclaration(
2066 FunctionExpression node, MethodElement getter, Node body, _) {
2067 return buildIrFunction(ir.ProcedureKind.Getter, getter, body);
2068 }
2069
2070 @override
2071 ir.Expression handleStaticGetterGet(Send node, FunctionElement getter, _) {
2072 if (getter.isDeferredLoaderGetter) {
2073 // TODO(ahe): Support deferred load.
2074 return new ir.InvalidExpression();
2075 }
2076 return buildStaticGet(getter);
2077 }
2078
2079 @override
2080 ir.Expression handleStaticGetterInvoke(Send node, FunctionElement getter,
2081 NodeList arguments, CallStructure callStructure, _) {
2082 if (getter.isDeferredLoaderGetter) {
2083 // TODO(ahe): Support deferred load.
2084 return new ir.InvalidExpression();
2085 }
2086 return buildCall(buildStaticGet(getter), callStructure, arguments);
2087 }
2088
2089 @override
2090 ir.Expression handleStaticGetterSet(
2091 SendSet node, FunctionElement getter, Node rhs, _) {
2092 return buildStaticAccessor(getter)
2093 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2094 }
2095
2096 @override
2097 IrFunction visitStaticSetterDeclaration(FunctionExpression node,
2098 MethodElement setter, NodeList parameters, Node body, _) {
2099 return buildIrFunction(ir.ProcedureKind.Setter, setter, body);
2100 }
2101
2102 @override
2103 ir.Expression handleStaticSetterGet(Send node, FunctionElement setter, _) {
2104 return buildStaticAccessor(null, setter).buildSimpleRead();
2105 }
2106
2107 @override
2108 ir.MethodInvocation handleStaticSetterInvoke(
2109 Send node,
2110 FunctionElement setter,
2111 NodeList arguments,
2112 CallStructure callStructure,
2113 _) {
2114 return buildCall(buildStaticAccessor(null, setter).buildSimpleRead(),
2115 callStructure, arguments);
2116 }
2117
2118 @override
2119 ir.Expression handleStaticSetterSet(
2120 SendSet node, FunctionElement setter, Node rhs, _) {
2121 return buildStaticAccessor(null, setter)
2122 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2123 }
2124
2125 @override
2126 ir.InvocationExpression visitStringFromEnvironmentConstructorInvoke(
2127 NewExpression node, StringFromEnvironmentConstantExpression constant, _) {
2128 return buildConstructorInvoke(node, isConst: true);
2129 }
2130
2131 @override
2132 ir.SuperMethodInvocation visitSuperBinary(Send node, FunctionElement function,
2133 BinaryOperator operator, Node argument, _) {
2134 return new ir.SuperMethodInvocation(kernel.functionToIr(function),
2135 new ir.Arguments(<ir.Expression>[visitForValue(argument)]));
2136 }
2137
2138 @override
2139 ir.Expression visitSuperCompoundIndexSet(
2140 SendSet node,
2141 MethodElement getter,
2142 MethodElement setter,
2143 Node index,
2144 AssignmentOperator operator,
2145 Node rhs,
2146 _) {
2147 return buildSuperIndexAccessor(index, getter, setter)
2148 .buildCompoundAssignment(
2149 kernel.irName(operator.selectorName, currentElement),
2150 visitForValue(rhs),
2151 voidContext: isVoidContext);
2152 }
2153
2154 @override
2155 ir.Initializer visitSuperConstructorInvoke(
2156 Send node,
2157 ConstructorElement superConstructor,
2158 InterfaceType type,
2159 NodeList arguments,
2160 CallStructure callStructure,
2161 _) {
2162 if (kernel.isSyntheticError(superConstructor)) {
2163 // TODO(ahe): Semantic visitor shouldn't call in this case.
2164 return new ir.InvalidInitializer();
2165 }
2166 return new ir.SuperInitializer(
2167 kernel.functionToIr(superConstructor), buildArguments(arguments));
2168 }
2169
2170 ir.SuperMethodInvocation buildSuperEquals(
2171 FunctionElement function, Node argument) {
2172 return new ir.SuperMethodInvocation(
2173 kernel.functionToIr(function),
2174 new ir.Arguments(<ir.Expression>[visitForValue(argument)],
2175 types: null, named: null));
2176 }
2177
2178 @override
2179 ir.SuperMethodInvocation visitSuperEquals(
2180 Send node, FunctionElement function, Node argument, _) {
2181 return buildSuperEquals(function, argument);
2182 }
2183
2184 @override
2185 ir.Expression handleSuperCompounds(
2186 SendSet node,
2187 Element getter,
2188 CompoundGetter getterKind,
2189 Element setter,
2190 CompoundSetter setterKind,
2191 CompoundRhs rhs,
2192 _) {
2193 if (setterKind == CompoundSetter.INVALID) {
2194 setter = null;
2195 }
2196 return buildCompound(buildSuperPropertyAccessor(getter, setter), rhs);
2197 }
2198
2199 @override
2200 ir.Expression handleStaticCompounds(
2201 SendSet node,
2202 Element getter,
2203 CompoundGetter getterKind,
2204 Element setter,
2205 CompoundSetter setterKind,
2206 CompoundRhs rhs,
2207 _) {
2208 if (setterKind == CompoundSetter.INVALID) {
2209 setter = null;
2210 }
2211 return buildCompound(buildStaticAccessor(getter, setter), rhs);
2212 }
2213
2214 @override
2215 ir.Expression handleTypeLiteralConstantCompounds(
2216 SendSet node, ConstantExpression constant, CompoundRhs rhs, _) {
2217 return buildCompound(new ReadOnlyAccessor(buildTypeLiteral(constant)), rhs);
2218 }
2219
2220 ir.TypeLiteral buildTypeVariable(TypeVariableElement element) {
2221 return new ir.TypeLiteral(kernel.typeToIr(element.type));
2222 }
2223
2224 @override
2225 ir.Expression handleTypeVariableTypeLiteralCompounds(
2226 SendSet node, TypeVariableElement element, CompoundRhs rhs, _) {
2227 return buildCompound(new ReadOnlyAccessor(buildTypeVariable(element)), rhs);
2228 }
2229
2230 @override
2231 ir.SuperPropertyGet visitSuperFieldGet(Send node, FieldElement field, _) {
2232 return buildSuperPropertyAccessor(field).buildSimpleRead();
2233 }
2234
2235 @override
2236 ir.MethodInvocation visitSuperFieldInvoke(Send node, FieldElement field,
2237 NodeList arguments, CallStructure callStructure, _) {
2238 return buildCall(buildSuperPropertyAccessor(field).buildSimpleRead(),
2239 callStructure, arguments);
2240 }
2241
2242 @override
2243 ir.Expression visitSuperFieldSet(
2244 SendSet node, FieldElement field, Node rhs, _) {
2245 return buildSuperPropertyAccessor(field)
2246 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2247 }
2248
2249 Accessor buildSuperPropertyAccessor(Element getter, [Element setter]) {
2250 if (setter == null &&
2251 getter.isField &&
2252 !getter.isFinal &&
2253 !getter.isConst) {
2254 setter = getter;
2255 }
2256 return new SuperPropertyAccessor(
2257 (getter == null) ? null : kernel.elementToIr(getter),
2258 (setter == null) ? null : kernel.elementToIr(setter));
2259 }
2260
2261 Accessor buildSuperIndexAccessor(Expression index, Element getter,
2262 [Element setter]) {
2263 if (setter == null &&
2264 getter.isField &&
2265 !getter.isFinal &&
2266 !getter.isConst) {
2267 setter = getter;
2268 }
2269 return new SuperIndexAccessor(
2270 visitForValue(index),
2271 (getter == null) ? null : kernel.elementToIr(getter),
2272 (setter == null) ? null : kernel.elementToIr(setter));
2273 }
2274
2275 @override
2276 ir.SuperPropertyGet visitSuperGetterGet(
2277 Send node, FunctionElement getter, _) {
2278 return buildSuperPropertyAccessor(getter).buildSimpleRead();
2279 }
2280
2281 @override
2282 ir.MethodInvocation visitSuperGetterInvoke(Send node, FunctionElement getter,
2283 NodeList arguments, CallStructure callStructure, _) {
2284 return buildCall(buildSuperPropertyAccessor(getter).buildSimpleRead(),
2285 callStructure, arguments);
2286 }
2287
2288 @override
2289 ir.Expression visitSuperGetterSet(
2290 SendSet node, FunctionElement getter, Node rhs, _) {
2291 return buildSuperPropertyAccessor(getter)
2292 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2293 }
2294
2295 @override
2296 ir.Expression handleSuperSetIfNulls(
2297 SendSet node,
2298 Element getter,
2299 CompoundGetter getterKind,
2300 Element setter,
2301 CompoundSetter setterKind,
2302 Node rhs,
2303 _) {
2304 if (setterKind == CompoundSetter.INVALID) {
2305 setter = null;
2306 }
2307 return buildSuperPropertyAccessor(getter, setter).buildNullAwareAssignment(
2308 visitForValue(rhs),
2309 voidContext: isVoidContext);
2310 }
2311
2312 @override
2313 ir.SuperMethodInvocation visitSuperIndex(
2314 Send node, FunctionElement function, Node index, _) {
2315 return buildSuperIndexAccessor(index, function).buildSimpleRead();
2316 }
2317
2318 @override
2319 ir.Expression visitSuperIndexPostfix(Send node, MethodElement indexFunction,
2320 MethodElement indexSetFunction, Node index, IncDecOperator operator, _) {
2321 Accessor accessor =
2322 buildSuperIndexAccessor(index, indexFunction, indexSetFunction);
2323 return buildIndexPostfix(accessor, operator);
2324 }
2325
2326 @override
2327 ir.Expression visitSuperIndexPrefix(Send node, MethodElement indexFunction,
2328 MethodElement indexSetFunction, Node index, IncDecOperator operator, _) {
2329 Accessor accessor =
2330 buildSuperIndexAccessor(index, indexFunction, indexSetFunction);
2331 return buildIndexPrefix(accessor, operator);
2332 }
2333
2334 @override
2335 ir.Expression visitSuperIndexSet(
2336 SendSet node, FunctionElement function, Node index, Node rhs, _) {
2337 return buildSuperIndexAccessor(index, null, function)
2338 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2339 }
2340
2341 @override
2342 ir.Expression visitSuperMethodGet(Send node, MethodElement method, _) {
2343 return buildSuperPropertyAccessor(method).buildSimpleRead();
2344 }
2345
2346 ir.SuperMethodInvocation buildSuperMethodInvoke(
2347 MethodElement method, NodeList arguments) {
2348 return new ir.SuperMethodInvocation(
2349 kernel.functionToIr(method), buildArguments(arguments));
2350 }
2351
2352 @override
2353 ir.SuperMethodInvocation visitSuperMethodIncompatibleInvoke(
2354 Send node,
2355 MethodElement method,
2356 NodeList arguments,
2357 CallStructure callStructure,
2358 _) {
2359 return buildSuperMethodInvoke(method, arguments);
2360 }
2361
2362 @override
2363 ir.SuperMethodInvocation visitSuperMethodInvoke(
2364 Send node,
2365 MethodElement method,
2366 NodeList arguments,
2367 CallStructure callStructure,
2368 _) {
2369 return buildSuperMethodInvoke(method, arguments);
2370 }
2371
2372 @override
2373 ir.Expression visitSuperMethodSet(
2374 Send node, MethodElement method, Node rhs, _) {
2375 return buildSuperPropertyAccessor(method)
2376 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2377 }
2378
2379 @override
2380 ir.Not visitSuperNotEquals(
2381 Send node, FunctionElement function, Node argument, _) {
2382 return new ir.Not(buildSuperEquals(function, argument));
2383 }
2384
2385 @override
2386 ir.Expression visitSuperSetterGet(Send node, FunctionElement setter, _) {
2387 return buildSuperPropertyAccessor(null, setter).buildSimpleRead();
2388 }
2389
2390 @override
2391 ir.MethodInvocation visitSuperSetterInvoke(Send node, FunctionElement setter,
2392 NodeList arguments, CallStructure callStructure, _) {
2393 return buildCall(buildSuperPropertyAccessor(null, setter).buildSimpleRead(),
2394 callStructure, arguments);
2395 }
2396
2397 @override
2398 ir.Expression visitSuperSetterSet(
2399 SendSet node, FunctionElement setter, Node rhs, _) {
2400 return buildSuperPropertyAccessor(null, setter)
2401 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2402 }
2403
2404 @override
2405 ir.SuperMethodInvocation visitSuperUnary(
2406 Send node, UnaryOperator operator, FunctionElement function, _) {
2407 return new ir.SuperMethodInvocation(
2408 kernel.functionToIr(function), new ir.Arguments.empty());
2409 }
2410
2411 @override
2412 ir.Initializer visitThisConstructorInvoke(
2413 Send node,
2414 ConstructorElement thisConstructor,
2415 NodeList arguments,
2416 CallStructure callStructure,
2417 _) {
2418 if (kernel.isSyntheticError(thisConstructor)) {
2419 return new ir.InvalidInitializer();
2420 } else {
2421 return new ir.RedirectingInitializer(
2422 kernel.functionToIr(thisConstructor), buildArguments(arguments));
2423 }
2424 }
2425
2426 @override
2427 ir.ThisExpression visitThisGet(Identifier node, _) {
2428 return new ir.ThisExpression();
2429 }
2430
2431 @override
2432 ir.MethodInvocation visitThisInvoke(
2433 Send node, NodeList arguments, CallStructure callStructure, _) {
2434 return buildCall(new ir.ThisExpression(), callStructure, arguments);
2435 }
2436
2437 Accessor buildThisPropertyAccessor(Name name) {
2438 return new ThisPropertyAccessor(nameToIrName(name));
2439 }
2440
2441 @override
2442 ir.Expression visitThisPropertyGet(Send node, Name name, _) {
2443 return buildThisPropertyAccessor(name).buildSimpleRead();
2444 }
2445
2446 @override
2447 ir.MethodInvocation visitThisPropertyInvoke(
2448 Send node, NodeList arguments, Selector selector, _) {
2449 return buildInvokeSelector(
2450 new ir.ThisExpression(), selector, buildArguments(arguments));
2451 }
2452
2453 @override
2454 ir.Expression visitThisPropertySet(SendSet node, Name name, Node rhs, _) {
2455 return buildThisPropertyAccessor(name)
2456 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2457 }
2458
2459 @override
2460 ir.Expression visitTopLevelConstantDeclaration(VariableDefinitions node,
2461 Node definition, FieldElement field, ConstantExpression constant, _) {
2462 // Shouldn't be called, handled by fieldToIr.
2463 return internalError(node, "TopLevelFieldDeclaration");
2464 }
2465
2466 @override
2467 ir.Expression visitTopLevelFieldDeclaration(VariableDefinitions node,
2468 Node definition, FieldElement field, Node initializer, _) {
2469 // Shouldn't be called, handled by fieldToIr.
2470 return internalError(node, "TopLevelFieldDeclaration");
2471 }
2472
2473 @override
2474 IrFunction visitTopLevelFunctionDeclaration(FunctionExpression node,
2475 MethodElement function, NodeList parameters, Node body, _) {
2476 return buildIrFunction(ir.ProcedureKind.Method, function, body);
2477 }
2478
2479 ir.Arguments buildArguments(NodeList arguments) {
2480 List<ir.Expression> positional = <ir.Expression>[];
2481 List<ir.NamedExpression> named = <ir.NamedExpression>[];
2482 for (Expression expression in arguments.nodes) {
2483 ir.TreeNode argument = visitForValue(expression);
2484 if (argument is ir.NamedExpression) {
2485 named.add(argument);
2486 } else {
2487 positional.add(argument);
2488 }
2489 }
2490 return new ir.Arguments(positional, named: named, types: null);
2491 }
2492
2493 @override
2494 IrFunction visitTopLevelGetterDeclaration(
2495 FunctionExpression node, MethodElement getter, Node body, _) {
2496 return buildIrFunction(ir.ProcedureKind.Getter, getter, body);
2497 }
2498
2499 @override
2500 IrFunction visitTopLevelSetterDeclaration(FunctionExpression node,
2501 MethodElement setter, NodeList parameters, Node body, _) {
2502 return buildIrFunction(ir.ProcedureKind.Setter, setter, body);
2503 }
2504
2505 @override
2506 ir.TypeLiteral visitTypeVariableTypeLiteralGet(
2507 Send node, TypeVariableElement element, _) {
2508 return buildTypeVariable(element);
2509 }
2510
2511 @override
2512 ir.MethodInvocation visitTypeVariableTypeLiteralInvoke(
2513 Send node,
2514 TypeVariableElement element,
2515 NodeList arguments,
2516 CallStructure callStructure,
2517 _) {
2518 return buildCall(buildTypeVariable(element), callStructure, arguments);
2519 }
2520
2521 @override
2522 ir.Expression visitTypeVariableTypeLiteralSet(
2523 SendSet node, TypeVariableElement element, Node rhs, _) {
2524 return new ReadOnlyAccessor(buildTypeVariable(element))
2525 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
2526 }
2527
2528 @override
2529 ir.Expression visitTypeVariableTypeLiteralSetIfNull(
2530 Send node, TypeVariableElement element, Node rhs, _) {
2531 return new ReadOnlyAccessor(buildTypeVariable(element))
2532 .buildNullAwareAssignment(visitForValue(rhs),
2533 voidContext: isVoidContext);
2534 }
2535
2536 @override
2537 ir.TypeLiteral visitTypedefTypeLiteralGet(
2538 Send node, ConstantExpression constant, _) {
2539 return buildTypeLiteral(constant);
2540 }
2541
2542 @override
2543 ir.MethodInvocation visitTypedefTypeLiteralInvoke(
2544 Send node,
2545 ConstantExpression constant,
2546 NodeList arguments,
2547 CallStructure callStructure,
2548 _) {
2549 return buildCall(buildTypeLiteral(constant), callStructure, arguments);
2550 }
2551
2552 @override
2553 ir.Expression visitTypedefTypeLiteralSet(
2554 SendSet node, ConstantExpression constant, Node rhs, _) {
2555 return buildTypeLiteralSet(constant, rhs);
2556 }
2557
2558 @override
2559 ir.Expression handleTypeLiteralConstantSetIfNulls(
2560 SendSet node, ConstantExpression constant, Node rhs, _) {
2561 // Degenerate case: ignores [rhs] as a type literal is never null.
2562 return buildTypeLiteral(constant);
2563 }
2564
2565 @override
2566 ir.MethodInvocation visitUnary(
2567 Send node, UnaryOperator operator, Node expression, _) {
2568 return new ir.MethodInvocation(
2569 visitForValue(expression),
2570 kernel.irName(operator.selectorName, currentElement),
2571 new ir.Arguments.empty());
2572 }
2573
2574 @override
2575 visitConditionalUri(ConditionalUri node) {
2576 // Shouldn't be called, handled by library loader.
2577 return internalError(node, "ConditionalUri");
2578 }
2579
2580 @override
2581 visitDottedName(DottedName node) {
2582 // Shouldn't be called, handled by library loader.
2583 return internalError(node, "DottedName");
2584 }
2585
2586 @override
2587 visitForIn(ForIn node) {
2588 // Shouldn't be called, handled by [visitAsyncForIn] or [visitSyncForIn].
2589 return internalError(node, "ForIn");
2590 }
2591
2592 @override
2593 ir.Expression visitIndexSetIfNull(
2594 SendSet node, Node receiver, Node index, Node rhs, _) {
2595 return buildIndexAccessor(receiver, index).buildNullAwareAssignment(
2596 visitForValue(rhs),
2597 voidContext: isVoidContext);
2598 }
2599
2600 @override
2601 ir.Expression visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
2602 MethodElement setter, Node index, Node rhs, _) {
2603 return buildSuperIndexAccessor(index, getter, setter)
2604 .buildNullAwareAssignment(visitForValue(rhs),
2605 voidContext: isVoidContext);
2606 }
2607
2608 @override
2609 ir.Node visitVariableDefinitions(VariableDefinitions definitions) {
2610 // TODO(ahe): This method is copied from [SemanticDeclarationResolvedMixin]
2611 // and modified. Perhaps we can find a way to avoid code duplication.
2612 List<ir.VariableDeclaration> variables = <ir.VariableDeclaration>[];
2613 computeVariableStructures(definitions,
2614 (Node node, VariableStructure structure) {
2615 if (structure == null) {
2616 return internalError(node, 'No structure for $node');
2617 } else {
2618 ir.VariableDeclaration variable =
2619 structure.dispatch(declVisitor, node, null);
2620 variables.add(variable);
2621 return variable;
2622 }
2623 });
2624 if (variables.length == 1) return variables.single;
2625 return new VariableDeclarations(variables);
2626 }
2627
2628 IrFunction buildFunction() {
2629 return kernel.compiler.reporter.withCurrentElement(currentElement, () {
2630 if (kernel.isSyntheticError(currentElement)) {
2631 kernel.internalError(currentElement,
2632 "Can't build synthetic function element: $currentElement");
2633 } else if (currentElement.isMalformed) {
2634 ir.FunctionNode node = buildFunctionNode(currentElement, null);
2635 if (currentElement.isGenerativeConstructor) {
2636 return new IrFunction.constructor(
2637 node, <ir.Initializer>[new ir.InvalidInitializer()]);
2638 } else {
2639 node.body = new ir.InvalidStatement()..parent = node;
2640 return new IrFunction.procedure(ir.ProcedureKind.Method, node);
2641 }
2642 } else if (currentElement.isSynthesized) {
2643 if (currentElement.isGenerativeConstructor) {
2644 return buildGenerativeConstructor(currentElement, null, null);
2645 } else {
2646 return internalError(currentElement, "Unhandled synthetic function.");
2647 }
2648 } else {
2649 Node node = currentElement.node;
2650 if (node.isErroneous) {
2651 return internalError(currentElement, "Unexpected syntax error.");
2652 } else {
2653 return node.accept(this);
2654 }
2655 }
2656 });
2657 }
2658
2659 ir.Expression buildInitializer() {
2660 return kernel.compiler.reporter.withCurrentElement(currentElement, () {
2661 FieldElement field = currentElement;
2662 return field.isMalformed
2663 ? new ir.InvalidExpression()
2664 : visitForValue(field.initializer);
2665 });
2666 }
2667 }
2668
2669 class VariableDeclarations implements ir.Node {
2670 final List<ir.VariableDeclaration> variables;
2671
2672 VariableDeclarations(this.variables);
2673
2674 accept(ir.Visitor v) => throw "unsupported";
2675
2676 visitChildren(ir.Visitor v) => throw "unsupported";
2677
2678 String toString() => "VariableDeclarations($variables)";
2679 }
2680
2681 class IrFunction implements ir.Node {
2682 final ir.ProcedureKind kind;
2683 final bool isConstructor;
2684 final ir.FunctionNode node;
2685 final List<ir.Initializer> initializers;
2686
2687 IrFunction(this.kind, this.isConstructor, this.node, this.initializers);
2688
2689 IrFunction.procedure(ir.ProcedureKind kind, ir.FunctionNode node)
2690 : this(kind, false, node, null);
2691
2692 IrFunction.constructor(
2693 ir.FunctionNode node, List<ir.Initializer> initializers)
2694 : this(null, true, node, initializers);
2695
2696 accept(ir.Visitor v) => throw "unsupported";
2697
2698 visitChildren(ir.Visitor v) => throw "unsupported";
2699
2700 String toString() {
2701 return "IrFunction($kind, $isConstructor, $node, $initializers)";
2702 }
2703 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/kernel.dart ('k') | pkg/compiler/lib/src/kernel/unavailable.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698