| // 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, |
| // TODO(johnniwinther): Store the call selector instead of the |
| // selector using the name of the function. |
| new Selector.callClosureFrom(selector), |
| arg); |
| case AccessKind.LOCAL_VARIABLE: |
| return visitor.visitLocalVariableInvoke( |
| node, |
| semantics.element, |
| node.argumentsNode, |
| // TODO(johnniwinther): Store the call selector instead of the |
| // selector using the name of the variable. |
| new Selector.callClosureFrom(selector), |
| arg); |
| case AccessKind.PARAMETER: |
| return visitor.visitParameterInvoke( |
| node, |
| semantics.element, |
| node.argumentsNode, |
| // TODO(johnniwinther): Store the call selector instead of the |
| // selector using the name of the parameter. |
| new Selector.callClosureFrom(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 index expression, i.e. of the form |
| /// `a[b]`. |
| class IndexStructure<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; |
| |
| IndexStructure(this.semantics, this.selector); |
| |
| R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) { |
| switch (semantics.kind) { |
| case AccessKind.DYNAMIC_PROPERTY: |
| return visitor.visitIndex( |
| node, |
| node.receiver, |
| node.arguments.single, |
| arg); |
| case AccessKind.SUPER_METHOD: |
| return visitor.visitSuperIndex( |
| node, |
| semantics.element, |
| node.arguments.single, |
| arg); |
| case AccessKind.UNRESOLVED: |
| return visitor.errorUnresolvedSuperIndex( |
| node, |
| semantics.element, |
| node.arguments.single, |
| arg); |
| default: |
| // This is not a valid case. |
| break; |
| } |
| throw new SpannableAssertionFailure(node, "Invalid index: ${semantics}"); |
| } |
| } |
| |
| /// 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 an prefix operation on an index |
| /// expression, i.e. of the form `--a[b]`. |
| class IndexPrefixStructure<R, A> implements SendStructure<R, A> { |
| /// The target of the left operand. |
| final AccessSemantics semantics; |
| |
| /// The `++` or `--` operator used in the operation. |
| final IncDecOperator operator; |
| |
| // TODO(johnniwinther): Should we store this? |
| /// The [Selector] for the `[]` invocation. |
| final Selector getterSelector; |
| |
| // TODO(johnniwinther): Should we store this? |
| /// The [Selector] for the `[]=` invocation. |
| final Selector setterSelector; |
| |
| IndexPrefixStructure(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.visitIndexPrefix( |
| node, |
| node.receiver, |
| node.arguments.single, |
| operator, |
| arg); |
| case AccessKind.UNRESOLVED: |
| return visitor.errorUnresolvedSuperIndexPrefix( |
| node, |
| semantics.element, |
| node.arguments.single, |
| operator, |
| arg); |
| case AccessKind.COMPOUND: |
| CompoundAccessSemantics compoundSemantics = semantics; |
| switch (compoundSemantics.compoundAccessKind) { |
| case CompoundAccessKind.SUPER_GETTER_SETTER: |
| return visitor.visitSuperIndexPrefix( |
| node, |
| compoundSemantics.getter, |
| compoundSemantics.setter, |
| node.arguments.single, |
| operator, |
| arg); |
| default: |
| // This is not a valid case. |
| break; |
| } |
| break; |
| default: |
| // This is not a valid case. |
| break; |
| } |
| throw new SpannableAssertionFailure( |
| node, "Invalid index prefix: ${semantics}"); |
| } |
| } |
| |
| /// The structure for a [Send] that is an postfix operation on an index |
| /// expression, i.e. of the form `a[b]++`. |
| class IndexPostfixStructure<R, A> implements SendStructure<R, A> { |
| /// The target of the left operand. |
| final AccessSemantics semantics; |
| |
| /// The `++` or `--` operator used in the operation. |
| final IncDecOperator operator; |
| |
| // TODO(johnniwinther): Should we store this? |
| /// The [Selector] for the `[]` invocation. |
| final Selector getterSelector; |
| |
| // TODO(johnniwinther): Should we store this? |
| /// The [Selector] for the `[]=` invocation. |
| final Selector setterSelector; |
| |
| IndexPostfixStructure(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.visitIndexPostfix( |
| node, |
| node.receiver, |
| node.arguments.single, |
| operator, |
| arg); |
| case AccessKind.UNRESOLVED: |
| return visitor.errorUnresolvedSuperIndexPostfix( |
| node, |
| semantics.element, |
| node.arguments.single, |
| operator, |
| arg); |
| case AccessKind.COMPOUND: |
| CompoundAccessSemantics compoundSemantics = semantics; |
| switch (compoundSemantics.compoundAccessKind) { |
| case CompoundAccessKind.SUPER_GETTER_SETTER: |
| return visitor.visitSuperIndexPostfix( |
| node, |
| compoundSemantics.getter, |
| compoundSemantics.setter, |
| node.arguments.single, |
| operator, |
| arg); |
| default: |
| // This is not a valid case. |
| break; |
| } |
| break; |
| default: |
| // This is not a valid case. |
| break; |
| } |
| throw new SpannableAssertionFailure( |
| node, "Invalid index postfix: ${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.errorClassTypeLiteralCompound( |
| node, |
| semantics.constant, |
| operator, |
| node.arguments.single, |
| arg); |
| case AccessKind.TYPEDEF_TYPE_LITERAL: |
| return visitor.errorTypedefTypeLiteralCompound( |
| node, |
| semantics.constant, |
| operator, |
| node.arguments.single, |
| arg); |
| case AccessKind.DYNAMIC_TYPE_LITERAL: |
| return visitor.errorDynamicTypeLiteralCompound( |
| node, |
| semantics.constant, |
| operator, |
| node.arguments.single, |
| arg); |
| case AccessKind.TYPE_PARAMETER_TYPE_LITERAL: |
| return visitor.errorTypeVariableTypeLiteralCompound( |
| 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.errorClassTypeLiteralPrefix( |
| node, |
| semantics.constant, |
| operator, |
| arg); |
| case AccessKind.TYPEDEF_TYPE_LITERAL: |
| return visitor.errorTypedefTypeLiteralPrefix( |
| node, |
| semantics.constant, |
| operator, |
| arg); |
| case AccessKind.DYNAMIC_TYPE_LITERAL: |
| return visitor.errorDynamicTypeLiteralPrefix( |
| node, |
| semantics.constant, |
| operator, |
| arg); |
| case AccessKind.TYPE_PARAMETER_TYPE_LITERAL: |
| return visitor.errorTypeVariableTypeLiteralPrefix( |
| 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.errorClassTypeLiteralPostfix( |
| node, |
| semantics.constant, |
| operator, |
| arg); |
| case AccessKind.TYPEDEF_TYPE_LITERAL: |
| return visitor.errorTypedefTypeLiteralPostfix( |
| node, |
| semantics.constant, |
| operator, |
| arg); |
| case AccessKind.DYNAMIC_TYPE_LITERAL: |
| return visitor.errorDynamicTypeLiteralPostfix( |
| node, |
| semantics.constant, |
| operator, |
| arg); |
| case AccessKind.TYPE_PARAMETER_TYPE_LITERAL: |
| return visitor.errorTypeVariableTypeLiteralPostfix( |
| 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}"); |
| } |
| } |
| |