| 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..10ee61498e3ca4efd337e82567a5759981b34f0d
|
| --- /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}");
|
| + }
|
| +}
|
| +
|
|
|