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

Unified Diff: pkg/compiler/lib/src/resolution/send_structure.dart

Issue 929113002: Add SemanticVisitor to dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated and extended Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/resolution/send_structure.dart
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
new file mode 100644
index 0000000000000000000000000000000000000000..5e564a2dfa1f5261ad41901e330a356ebe6b9bce
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -0,0 +1,1594 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.send_structure;
+
+import 'access_semantics.dart';
+import 'operators.dart';
+import 'semantic_visitor.dart';
+import '../tree/tree.dart';
+import '../dart_types.dart';
+import '../universe/universe.dart';
+import '../util/util.dart';
+
+/// Interface for the structure of the semantics of a [Send] node.
+///
+/// Subclasses handle each of the [Send] variations; `assert(e)`, `a && b`,
+/// `a.b`, `a.b(c)`, etc.
+abstract class SendStructure<R, A> {
+ /// Calls the matching visit method on [visitor] with [send] and [arg].
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg);
+}
+
+/// The structure for a [Send] of the form `assert(e)`.
+class AssertStructure<R, A> implements SendStructure<R, A> {
+ const AssertStructure();
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.visitAssert(
+ node,
+ node.arguments.single,
+ arg);
+ }
+}
+
+/// The structure for a [Send] of the form an `assert` with less or more than
+/// one argument.
+class InvalidAssertStructure<R, A> implements SendStructure<R, A> {
+ const InvalidAssertStructure();
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.errorInvalidAssert(
+ node,
+ node.argumentsNode,
+ arg);
+ }
+}
+
+/// The structure for a [Send] of the form `a && b`.
+class LogicalAndStructure<R, A> implements SendStructure<R, A> {
+ const LogicalAndStructure();
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.visitLogicalAnd(
+ node,
+ node.receiver,
+ node.arguments.single,
+ arg);
+ }
+}
+
+/// The structure for a [Send] of the form `a || b`.
+class LogicalOrStructure<R, A> implements SendStructure<R, A> {
+ const LogicalOrStructure();
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.visitLogicalOr(
+ node,
+ node.receiver,
+ node.arguments.single,
+ arg);
+ }
+}
+
+/// The structure for a [Send] of the form `a is T`.
+class IsStructure<R, A> implements SendStructure<R, A> {
+ /// The type that the expression is tested against.
+ final DartType type;
+
+ IsStructure(this.type);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.visitIs(
+ node,
+ node.receiver,
+ type,
+ arg);
+ }
+}
+
+/// The structure for a [Send] of the form `a is! T`.
+class IsNotStructure<R, A> implements SendStructure<R, A> {
+ /// The type that the expression is tested against.
+ final DartType type;
+
+ IsNotStructure(this.type);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.visitIsNot(
+ node,
+ node.receiver,
+ type,
+ arg);
+ }
+}
+
+/// The structure for a [Send] of the form `a as T`.
+class AsStructure<R, A> implements SendStructure<R, A> {
+ /// The type that the expression is cast to.
+ final DartType type;
+
+ AsStructure(this.type);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.visitAs(
+ node,
+ node.receiver,
+ type,
+ arg);
+ }
+}
+
+/// The structure for a [Send] that is an invocation.
+class InvokeStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the invocation.
+ final AccessSemantics semantics;
+
+ /// The [Selector] for the invocation.
+ final Selector selector;
+
+ InvokeStructure(this.semantics, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitDynamicPropertyInvoke(
+ node,
+ node.receiver,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitor.visitLocalFunctionInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitor.visitLocalVariableInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.PARAMETER:
+ return visitor.visitParameterInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.STATIC_FIELD:
+ return visitor.visitStaticFieldInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.STATIC_METHOD:
+ return visitor.visitStaticFunctionInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.STATIC_GETTER:
+ return visitor.visitStaticGetterInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.STATIC_SETTER:
+ return visitor.errorStaticSetterInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.TOPLEVEL_FIELD:
+ return visitor.visitTopLevelFieldInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.TOPLEVEL_METHOD:
+ return visitor.visitTopLevelFunctionInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.TOPLEVEL_GETTER:
+ return visitor.visitTopLevelGetterInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.TOPLEVEL_SETTER:
+ return visitor.errorTopLevelSetterInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.CLASS_TYPE_LITERAL:
+ return visitor.visitClassTypeLiteralInvoke(
+ node,
+ semantics.constant,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.TYPEDEF_TYPE_LITERAL:
+ return visitor.visitTypedefTypeLiteralInvoke(
+ node,
+ semantics.constant,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.DYNAMIC_TYPE_LITERAL:
+ return visitor.visitDynamicTypeLiteralInvoke(
+ node,
+ semantics.constant,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+ return visitor.visitTypeVariableTypeLiteralInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.EXPRESSION:
+ return visitor.visitExpressionInvoke(
+ node,
+ node.selector,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.THIS:
+ return visitor.visitThisInvoke(
+ node,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.THIS_PROPERTY:
+ return visitor.visitThisPropertyInvoke(
+ node,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.SUPER_FIELD:
+ return visitor.visitSuperFieldInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.visitSuperMethodInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.SUPER_GETTER:
+ return visitor.visitSuperGetterInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.SUPER_SETTER:
+ return visitor.errorSuperSetterInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.CONSTANT:
+ return visitor.visitConstantInvoke(
+ node,
+ semantics.constant,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedInvoke(
+ node,
+ semantics.element,
+ node.argumentsNode,
+ selector,
+ arg);
+ case AccessKind.COMPOUND:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(node, "Invalid invoke: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is a read access.
+class GetStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the read access.
+ final AccessSemantics semantics;
+
+ /// The [Selector] for the getter invocation.
+ final Selector selector;
+
+ GetStructure(this.semantics, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitDynamicPropertyGet(
+ node,
+ node.receiver,
+ selector,
+ arg);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitor.visitLocalFunctionGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitor.visitLocalVariableGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.PARAMETER:
+ return visitor.visitParameterGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.STATIC_FIELD:
+ return visitor.visitStaticFieldGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.STATIC_METHOD:
+ return visitor.visitStaticFunctionGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.STATIC_GETTER:
+ return visitor.visitStaticGetterGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.STATIC_SETTER:
+ return visitor.errorStaticSetterGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.TOPLEVEL_FIELD:
+ return visitor.visitTopLevelFieldGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.TOPLEVEL_METHOD:
+ return visitor.visitTopLevelFunctionGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.TOPLEVEL_GETTER:
+ return visitor.visitTopLevelGetterGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.TOPLEVEL_SETTER:
+ return visitor.errorTopLevelSetterGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.CLASS_TYPE_LITERAL:
+ return visitor.visitClassTypeLiteralGet(
+ node,
+ semantics.constant,
+ arg);
+ case AccessKind.TYPEDEF_TYPE_LITERAL:
+ return visitor.visitTypedefTypeLiteralGet(
+ node,
+ semantics.constant,
+ arg);
+ case AccessKind.DYNAMIC_TYPE_LITERAL:
+ return visitor.visitDynamicTypeLiteralGet(
+ node,
+ semantics.constant,
+ arg);
+ case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+ return visitor.visitTypeVariableTypeLiteralGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.EXPRESSION:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS:
+ // TODO(johnniwinther): Handle this when `this` is a [Send].
+ break;
+ case AccessKind.THIS_PROPERTY:
+ return visitor.visitThisPropertyGet(
+ node,
+ selector,
+ arg);
+ case AccessKind.SUPER_FIELD:
+ return visitor.visitSuperFieldGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.visitSuperMethodGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.SUPER_GETTER:
+ return visitor.visitSuperGetterGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.SUPER_SETTER:
+ return visitor.errorSuperSetterGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.CONSTANT:
+ return visitor.visitConstantGet(
+ node,
+ semantics.constant,
+ arg);
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedGet(
+ node,
+ semantics.element,
+ arg);
+ case AccessKind.COMPOUND:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(node, "Invalid getter: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is an assignment.
+class SetStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the assignment.
+ final AccessSemantics semantics;
+
+ /// The [Selector] for the setter invocation.
+ final Selector selector;
+
+ SetStructure(this.semantics, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitDynamicPropertySet(
+ node,
+ node.receiver,
+ selector,
+ node.arguments.single,
+ arg);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitor.errorLocalFunctionSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitor.visitLocalVariableSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.PARAMETER:
+ return visitor.visitParameterSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.STATIC_FIELD:
+ return visitor.visitStaticFieldSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.STATIC_METHOD:
+ return visitor.errorStaticFunctionSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.STATIC_GETTER:
+ return visitor.errorStaticGetterSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.STATIC_SETTER:
+ return visitor.visitStaticSetterSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.TOPLEVEL_FIELD:
+ return visitor.visitTopLevelFieldSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.TOPLEVEL_METHOD:
+ return visitor.errorTopLevelFunctionSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.TOPLEVEL_GETTER:
+ return visitor.errorTopLevelGetterSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.TOPLEVEL_SETTER:
+ return visitor.visitTopLevelSetterSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.CLASS_TYPE_LITERAL:
+ return visitor.errorClassTypeLiteralSet(
+ node,
+ semantics.constant,
+ node.arguments.single,
+ arg);
+ case AccessKind.TYPEDEF_TYPE_LITERAL:
+ return visitor.errorTypedefTypeLiteralSet(
+ node,
+ semantics.constant,
+ node.arguments.single,
+ arg);
+ case AccessKind.DYNAMIC_TYPE_LITERAL:
+ return visitor.errorDynamicTypeLiteralSet(
+ node,
+ semantics.constant,
+ node.arguments.single,
+ arg);
+ case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+ return visitor.errorTypeVariableTypeLiteralSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.EXPRESSION:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS_PROPERTY:
+ return visitor.visitThisPropertySet(
+ node,
+ selector,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_FIELD:
+ return visitor.visitSuperFieldSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.errorSuperMethodSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_GETTER:
+ return visitor.errorSuperGetterSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_SETTER:
+ return visitor.visitSuperSetterSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.CONSTANT:
+ // TODO(johnniwinther): Should this be a valid case?
+ break;
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedSet(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ case AccessKind.COMPOUND:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is a negation, i.e. of the form `!e`.
+class NotStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the negation.
+ final AccessSemantics semantics;
+
+ // TODO(johnniwinther): Should we store this?
+ final Selector selector;
+
+ NotStructure(this.semantics, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitNot(
+ node,
+ node.receiver,
+ arg);
+ default:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is an invocation of a user definable unary
+/// operator.
+class UnaryStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the unary operation.
+ final AccessSemantics semantics;
+
+ /// The user definable unary operator.
+ final UnaryOperator operator;
+
+ // TODO(johnniwinther): Should we store this?
+ /// The [Selector] for the unary operator invocation.
+ final Selector selector;
+
+ UnaryStructure(this.semantics, this.operator, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitUnary(
+ node,
+ operator,
+ node.receiver,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.visitSuperUnary(
+ node,
+ operator,
+ semantics.element,
+ arg);
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedSuperUnary(
+ node,
+ operator,
+ semantics.element,
+ arg);
+ default:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is an invocation of a undefined unary
+/// operator.
+class InvalidUnaryStructure<R, A> implements SendStructure<R, A> {
+ const InvalidUnaryStructure();
+
+ @override
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.errorUndefinedUnaryExpression(
+ node,
+ node.selector,
+ node.receiver,
+ arg);
+ }
+}
+
+/// The structure for a [Send] that is an equals test, i.e. of the form
+/// `a == b`.
+class EqualsStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the left operand.
+ final AccessSemantics semantics;
+
+ // TODO(johnniwinther): Should we store this?
+ /// The [Selector] for the `==` invocation.
+ final Selector selector;
+
+ EqualsStructure(this.semantics, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitEquals(
+ node,
+ node.receiver,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.visitSuperEquals(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ default:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(node, "Invalid equals: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is a not-equals test, i.e. of the form
+/// `a != b`.
+class NotEqualsStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the left operand.
+ final AccessSemantics semantics;
+
+ // TODO(johnniwinther): Should we store this?
+ /// The [Selector] for the underlying `==` invocation.
+ final Selector selector;
+
+ NotEqualsStructure(this.semantics, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitNotEquals(
+ node,
+ node.receiver,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.visitSuperNotEquals(
+ node,
+ semantics.element,
+ node.arguments.single,
+ arg);
+ default:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(
+ node, "Invalid not equals: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is an invocation of a user-definable binary
+/// operator.
+class BinaryStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the left operand.
+ final AccessSemantics semantics;
+
+ /// The user definable binary operator.
+ final BinaryOperator operator;
+
+ // TODO(johnniwinther): Should we store this?
+ /// The [Selector] for the binary operator invocation.
+ final Selector selector;
+
+ BinaryStructure(this.semantics, this.operator, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitBinary(
+ node,
+ node.receiver,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.visitSuperBinary(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedSuperBinary(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ default:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(
+ node, "Invalid binary: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is an invocation of a undefined binary
+/// operator.
+class InvalidBinaryStructure<R, A> implements SendStructure<R, A> {
+ const InvalidBinaryStructure();
+
+ @override
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ return visitor.errorUndefinedBinaryExpression(
+ node,
+ node.receiver,
+ node.selector,
+ node.arguments.single,
+ arg);
+ }
+}
+
+/// The structure for a [Send] that is of the form `a[b] = c`.
+class IndexSetStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the index set operation.
+ final AccessSemantics semantics;
+
+ // TODO(johnniwinther): Should we store this?
+ /// The [Selector] for the `[]=` operator invocation.
+ final Selector selector;
+
+ IndexSetStructure(this.semantics, this.selector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitIndexSet(
+ node,
+ node.receiver,
+ node.arguments.first,
+ node.arguments.tail.head,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ return visitor.visitSuperIndexSet(
+ node,
+ semantics.element,
+ node.arguments.first,
+ node.arguments.tail.head,
+ arg);
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedSuperIndexSet(
+ node,
+ semantics.element,
+ node.arguments.first,
+ node.arguments.tail.head,
+ arg);
+ default:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(
+ node, "Invalid index set: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is a compound assignment. For instance
+/// `a += b`.
+class CompoundStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the compound assignment, i.e. the left-hand side.
+ final AccessSemantics semantics;
+
+ /// The assignment operator used in the compound assignment.
+ final AssignmentOperator operator;
+
+ /// The [Selector] for the getter invocation.
+ final Selector getterSelector;
+
+ /// The [Selector] for the setter invocation.
+ final Selector setterSelector;
+
+ CompoundStructure(this.semantics,
+ this.operator,
+ this.getterSelector,
+ this.setterSelector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitDynamicPropertyCompound(
+ node,
+ node.receiver,
+ operator,
+ node.arguments.single,
+ getterSelector,
+ setterSelector,
+ arg);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitor.errorLocalFunctionCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitor.visitLocalVariableCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.PARAMETER:
+ return visitor.visitParameterCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.STATIC_FIELD:
+ return visitor.visitStaticFieldCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.STATIC_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.STATIC_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.STATIC_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.TOPLEVEL_FIELD:
+ return visitor.visitTopLevelFieldCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.TOPLEVEL_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.TOPLEVEL_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.TOPLEVEL_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.CLASS_TYPE_LITERAL:
+ return visitor.visitClassTypeLiteralCompound(
+ node,
+ semantics.constant,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.TYPEDEF_TYPE_LITERAL:
+ return visitor.visitTypedefTypeLiteralCompound(
+ node,
+ semantics.constant,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.DYNAMIC_TYPE_LITERAL:
+ return visitor.visitDynamicTypeLiteralCompound(
+ node,
+ semantics.constant,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+ return visitor.visitTypeVariableTypeLiteralCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.EXPRESSION:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS_PROPERTY:
+ return visitor.visitThisPropertyCompound(
+ node,
+ operator,
+ node.arguments.single,
+ getterSelector,
+ setterSelector,
+ arg);
+ case AccessKind.SUPER_FIELD:
+ return visitor.visitSuperFieldCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.SUPER_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.SUPER_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.CONSTANT:
+ // TODO(johnniwinther): Should this be a valid case?
+ break;
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedCompound(
+ node,
+ semantics.element,
+ operator,
+ node.arguments.single,
+ arg);
+ case AccessKind.COMPOUND:
+ CompoundAccessSemantics compoundSemantics = semantics;
+ switch (compoundSemantics.compoundAccessKind) {
+ case CompoundAccessKind.STATIC_GETTER_SETTER:
+ return visitor.visitStaticGetterSetterCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ case CompoundAccessKind.STATIC_METHOD_SETTER:
+ return visitor.visitStaticMethodSetterCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
+ return visitor.visitTopLevelGetterSetterCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
+ return visitor.visitTopLevelMethodSetterCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ case CompoundAccessKind.SUPER_FIELD_FIELD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case CompoundAccessKind.SUPER_GETTER_SETTER:
+ return visitor.visitSuperGetterSetterCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ case CompoundAccessKind.SUPER_GETTER_FIELD:
+ return visitor.visitSuperGetterFieldCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ case CompoundAccessKind.SUPER_METHOD_SETTER:
+ return visitor.visitSuperMethodSetterCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ case CompoundAccessKind.SUPER_FIELD_SETTER:
+ return visitor.visitSuperFieldSetterCompound(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ node.arguments.single,
+ arg);
+ }
+ break;
+ }
+ throw new SpannableAssertionFailure(node,
+ "Invalid compound assigment: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is a compound assignment on the index
+/// operator. For instance `a[b] += c`.
+class CompoundIndexSetStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the index operations.
+ final AccessSemantics semantics;
+
+ /// The assignment operator used in the compound assignment.
+ final AssignmentOperator operator;
+
+ /// The [Selector] for the `[]` operator invocation.
+ final Selector getterSelector;
+
+ /// The [Selector] for the `[]=` operator invocation.
+ final Selector setterSelector;
+
+ CompoundIndexSetStructure(this.semantics, this.operator,
+ this.getterSelector,
+ this.setterSelector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitCompoundIndexSet(
+ node,
+ node.receiver,
+ node.arguments.first,
+ operator,
+ node.arguments.tail.head,
+ arg);
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedSuperCompoundIndexSet(
+ node,
+ semantics.element,
+ node.arguments.first,
+ operator,
+ node.arguments.tail.head,
+ arg);
+ case AccessKind.COMPOUND:
+ CompoundAccessSemantics compoundSemantics = semantics;
+ switch (compoundSemantics.compoundAccessKind) {
+ case CompoundAccessKind.SUPER_GETTER_SETTER:
+ return visitor.visitSuperCompoundIndexSet(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ node.arguments.first,
+ operator,
+ node.arguments.tail.head,
+ arg);
+ default:
+ // This is not a valid case.
+ break;
+ }
+ break;
+ default:
+ // This is not a valid case.
+ break;
+ }
+ throw new SpannableAssertionFailure(
+ node, "Invalid compound index set: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is a prefix operations. For instance
+/// `++a`.
+class PrefixStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the prefix operation.
+ final AccessSemantics semantics;
+
+ /// The `++` or `--` operator used in the operation.
+ final IncDecOperator operator;
+
+ /// The [Selector] for the getter invocation.
+ final Selector getterSelector;
+
+ /// The [Selector] for the setter invocation.
+ final Selector setterSelector;
+
+ PrefixStructure(this.semantics,
+ this.operator,
+ this.getterSelector,
+ this.setterSelector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitDynamicPropertyPrefix(
+ node,
+ node.receiver,
+ operator,
+ getterSelector,
+ setterSelector,
+ arg);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitor.errorLocalFunctionPrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitor.visitLocalVariablePrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.PARAMETER:
+ return visitor.visitParameterPrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.STATIC_FIELD:
+ return visitor.visitStaticFieldPrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.STATIC_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.STATIC_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.STATIC_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.TOPLEVEL_FIELD:
+ return visitor.visitTopLevelFieldPrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.TOPLEVEL_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.TOPLEVEL_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.TOPLEVEL_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.CLASS_TYPE_LITERAL:
+ return visitor.visitClassTypeLiteralPrefix(
+ node,
+ semantics.constant,
+ operator,
+ arg);
+ case AccessKind.TYPEDEF_TYPE_LITERAL:
+ return visitor.visitTypedefTypeLiteralPrefix(
+ node,
+ semantics.constant,
+ operator,
+ arg);
+ case AccessKind.DYNAMIC_TYPE_LITERAL:
+ return visitor.visitDynamicTypeLiteralPrefix(
+ node,
+ semantics.constant,
+ operator,
+ arg);
+ case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+ return visitor.visitTypeVariableTypeLiteralPrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.EXPRESSION:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS_PROPERTY:
+ return visitor.visitThisPropertyPrefix(
+ node,
+ operator,
+ getterSelector,
+ setterSelector,
+ arg);
+ case AccessKind.SUPER_FIELD:
+ return visitor.visitSuperFieldPrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.SUPER_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.SUPER_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.CONSTANT:
+ // TODO(johnniwinther): Should this be a valid case?
+ break;
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedPrefix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.COMPOUND:
+ CompoundAccessSemantics compoundSemantics = semantics;
+ switch (compoundSemantics.compoundAccessKind) {
+ case CompoundAccessKind.STATIC_GETTER_SETTER:
+ return visitor.visitStaticGetterSetterPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.STATIC_METHOD_SETTER:
+ return visitor.visitStaticMethodSetterPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
+ return visitor.visitTopLevelGetterSetterPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
+ return visitor.visitTopLevelMethodSetterPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_FIELD_FIELD:
+ return visitor.visitSuperFieldFieldPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_GETTER_SETTER:
+ return visitor.visitSuperGetterSetterPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_GETTER_FIELD:
+ return visitor.visitSuperGetterFieldPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_METHOD_SETTER:
+ return visitor.visitSuperMethodSetterPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_FIELD_SETTER:
+ return visitor.visitSuperFieldSetterPrefix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ }
+ }
+ throw new SpannableAssertionFailure(node,
+ "Invalid compound assigment: ${semantics}");
+ }
+}
+
+/// The structure for a [Send] that is a postfix operations. For instance
+/// `a++`.
+class PostfixStructure<R, A> implements SendStructure<R, A> {
+ /// The target of the postfix operation.
+ final AccessSemantics semantics;
+
+ /// The `++` or `--` operator used in the operation.
+ final IncDecOperator operator;
+
+ /// The [Selector] for the getter invocation.
+ final Selector getterSelector;
+
+ /// The [Selector] for the setter invocation.
+ final Selector setterSelector;
+
+ PostfixStructure(this.semantics,
+ this.operator,
+ this.getterSelector,
+ this.setterSelector);
+
+ R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC_PROPERTY:
+ return visitor.visitDynamicPropertyPostfix(
+ node,
+ node.receiver,
+ operator,
+ getterSelector,
+ setterSelector,
+ arg);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitor.errorLocalFunctionPostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitor.visitLocalVariablePostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.PARAMETER:
+ return visitor.visitParameterPostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.STATIC_FIELD:
+ return visitor.visitStaticFieldPostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.STATIC_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.STATIC_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.STATIC_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.TOPLEVEL_FIELD:
+ return visitor.visitTopLevelFieldPostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.TOPLEVEL_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.TOPLEVEL_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.TOPLEVEL_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.CLASS_TYPE_LITERAL:
+ return visitor.visitClassTypeLiteralPostfix(
+ node,
+ semantics.constant,
+ operator,
+ arg);
+ case AccessKind.TYPEDEF_TYPE_LITERAL:
+ return visitor.visitTypedefTypeLiteralPostfix(
+ node,
+ semantics.constant,
+ operator,
+ arg);
+ case AccessKind.DYNAMIC_TYPE_LITERAL:
+ return visitor.visitDynamicTypeLiteralPostfix(
+ node,
+ semantics.constant,
+ operator,
+ arg);
+ case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+ return visitor.visitTypeVariableTypeLiteralPostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.EXPRESSION:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS:
+ // This is not a valid case.
+ break;
+ case AccessKind.THIS_PROPERTY:
+ return visitor.visitThisPropertyPostfix(
+ node,
+ operator,
+ getterSelector,
+ setterSelector,
+ arg);
+ case AccessKind.SUPER_FIELD:
+ return visitor.visitSuperFieldPostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.SUPER_METHOD:
+ // TODO(johnniwinther): Handle this.
+ break;
+ case AccessKind.SUPER_GETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.SUPER_SETTER:
+ // This is not a valid case.
+ break;
+ case AccessKind.CONSTANT:
+ // TODO(johnniwinther): Should this be a valid case?
+ break;
+ case AccessKind.UNRESOLVED:
+ return visitor.errorUnresolvedPostfix(
+ node,
+ semantics.element,
+ operator,
+ arg);
+ case AccessKind.COMPOUND:
+ CompoundAccessSemantics compoundSemantics = semantics;
+ switch (compoundSemantics.compoundAccessKind) {
+ case CompoundAccessKind.STATIC_GETTER_SETTER:
+ return visitor.visitStaticGetterSetterPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.STATIC_METHOD_SETTER:
+ return visitor.visitStaticMethodSetterPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
+ return visitor.visitTopLevelGetterSetterPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
+ return visitor.visitTopLevelMethodSetterPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_FIELD_FIELD:
+ return visitor.visitSuperFieldFieldPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_GETTER_SETTER:
+ return visitor.visitSuperGetterSetterPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_GETTER_FIELD:
+ return visitor.visitSuperGetterFieldPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_METHOD_SETTER:
+ return visitor.visitSuperMethodSetterPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ case CompoundAccessKind.SUPER_FIELD_SETTER:
+ return visitor.visitSuperFieldSetterPostfix(
+ node,
+ compoundSemantics.getter,
+ compoundSemantics.setter,
+ operator,
+ arg);
+ }
+ }
+ throw new SpannableAssertionFailure(node,
+ "Invalid compound assigment: ${semantics}");
+ }
+}
+

Powered by Google App Engine
This is Rietveld 408576698