Chromium Code Reviews| 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..a0710226ec5605977e4c9dea701e24740991017c |
| --- /dev/null |
| +++ b/pkg/compiler/lib/src/resolution/send_structure.dart |
| @@ -0,0 +1,1364 @@ |
| +// 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'; |
| + |
| +abstract class SendStructure<R, A> { |
|
karlklose
2015/02/25 12:39:39
Please add documentation for this class hierarchy.
Johnni Winther
2015/03/04 11:59:39
Done.
|
| + R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg); |
| +} |
| + |
| +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); |
| + } |
| +} |
| + |
| +class LazyAndStructure<R, A> implements SendStructure<R, A> { |
| + const LazyAndStructure(); |
| + |
| + R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) { |
| + return visitor.visitLazyAnd( |
| + node, |
| + node.receiver, |
| + node.arguments.single, |
| + arg); |
| + } |
| +} |
| + |
| +class LazyOrStructure<R, A> implements SendStructure<R, A> { |
| + const LazyOrStructure(); |
| + |
| + R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) { |
| + return visitor.visitLazyOr( |
| + node, |
| + node.receiver, |
| + node.arguments.single, |
| + arg); |
| + } |
| +} |
| + |
| +class IsStructure<R, A> implements SendStructure<R, A> { |
| + final DartType type; |
| + |
| + IsStructure(this.type); |
| + |
| + R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) { |
| + return visitor.visitIs( |
| + node, |
| + node.receiver, |
| + type, |
| + arg); |
| + } |
| +} |
| + |
| +class IsNotStructure<R, A> implements SendStructure<R, A> { |
| + final DartType type; |
| + |
| + IsNotStructure(this.type); |
| + |
| + R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) { |
| + return visitor.visitIsNot( |
| + node, |
| + node.receiver, |
| + type, |
| + arg); |
| + } |
| +} |
| + |
| +class AsStructure<R, A> implements SendStructure<R, A> { |
| + final DartType type; |
| + |
| + AsStructure(this.type); |
| + |
| + R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) { |
| + return visitor.visitAs( |
| + node, |
| + node.receiver, |
| + type, |
| + arg); |
| + } |
| +} |
| + |
| +class InvokeStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + 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.element, |
| + node.argumentsNode, |
| + selector, |
| + arg); |
| + case AccessKind.TYPEDEF_TYPE_LITERAL: |
| + return visitor.visitTypedefTypeLiteralInvoke( |
| + node, |
| + semantics.element, |
| + node.argumentsNode, |
| + selector, |
| + arg); |
| + case AccessKind.DYNAMIC_TYPE_LITERAL: |
| + return visitor.visitDynamicTypeLiteralInvoke( |
| + node, |
| + 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.COMPOUND: |
| + // This is not a valid case. |
|
karlklose
2015/02/25 12:39:39
Shouldn't these cases throw too?
Johnni Winther
2015/03/04 11:59:39
No. Compound means that we both a getter and sette
|
| + break; |
| + } |
| + throw new SpannableAssertionFailure(node, "Invalid invoke: ${semantics}"); |
| + } |
| +} |
| + |
| + |
| +class GetStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + 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.element, |
| + arg); |
| + case AccessKind.TYPEDEF_TYPE_LITERAL: |
| + return visitor.visitTypedefTypeLiteralGet( |
| + node, |
| + semantics.element, |
| + arg); |
| + case AccessKind.DYNAMIC_TYPE_LITERAL: |
| + return visitor.visitDynamicTypeLiteralGet( |
| + node, |
| + 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.COMPOUND: |
| + // This is not a valid case. |
| + break; |
| + } |
| + throw new SpannableAssertionFailure(node, "Invalid getter: ${semantics}"); |
| + } |
| +} |
| + |
| +class SetStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + 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.element, |
| + node.arguments.single, |
| + arg); |
| + case AccessKind.TYPEDEF_TYPE_LITERAL: |
| + return visitor.errorTypedefTypeLiteralSet( |
| + node, |
| + semantics.element, |
| + node.arguments.single, |
| + arg); |
| + case AccessKind.DYNAMIC_TYPE_LITERAL: |
| + return visitor.errorDynamicTypeLiteralSet( |
| + node, |
| + 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.COMPOUND: |
| + // This is not a valid case. |
| + break; |
| + } |
| + throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}"); |
| + } |
| +} |
| + |
| +class NotStructure<R, A> implements SendStructure<R, A> { |
| + 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}"); |
| + } |
| +} |
| + |
| +class UnaryStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + final UnaryOperator operator; |
| + // TODO(johnniwinther): Should we store this? |
| + 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); |
| + default: |
| + // This is not a valid case. |
| + break; |
| + } |
| + throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}"); |
| + } |
| +} |
| + |
| +class EqualsStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + // TODO(johnniwinther): Should we store this? |
| + 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}"); |
| + } |
| +} |
| + |
| +class NotEqualsStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + // TODO(johnniwinther): Should we store this? |
| + 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}"); |
| + } |
| +} |
| + |
| +class BinaryStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + final BinaryOperator operator; |
| + // TODO(johnniwinther): Should we store this? |
| + 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); |
| + default: |
| + // This is not a valid case. |
| + break; |
| + } |
| + throw new SpannableAssertionFailure( |
| + node, "Invalid binary: ${semantics}"); |
| + } |
| +} |
| + |
| +class IndexSetStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + // TODO(johnniwinther): Should we store this? |
| + 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); |
| + default: |
| + // This is not a valid case. |
| + break; |
| + } |
| + throw new SpannableAssertionFailure( |
| + node, "Invalid index set: ${semantics}"); |
| + } |
| +} |
| + |
| +class CompoundStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + final AssignmentOperator operator; |
| + final Selector getterSelector; |
| + 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.element, |
| + operator, |
| + node.arguments.single, |
| + arg); |
| + case AccessKind.TYPEDEF_TYPE_LITERAL: |
| + return visitor.visitTypedefTypeLiteralCompound( |
| + node, |
| + semantics.element, |
| + operator, |
| + node.arguments.single, |
| + arg); |
| + case AccessKind.DYNAMIC_TYPE_LITERAL: |
| + return visitor.visitDynamicTypeLiteralCompound( |
| + node, |
| + 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.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}"); |
| + } |
| +} |
| + |
| +class CompoundIndexSetStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + final AssignmentOperator operator; |
| + final Selector getterSelector; |
| + 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.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 index set: ${semantics}"); |
| + } |
| +} |
| + |
| +class PrefixStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + final IncDecOperator operator; |
| + final Selector getterSelector; |
| + 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.element, |
| + operator, |
| + arg); |
| + case AccessKind.TYPEDEF_TYPE_LITERAL: |
| + return visitor.visitTypedefTypeLiteralPrefix( |
| + node, |
| + semantics.element, |
| + operator, |
| + arg); |
| + case AccessKind.DYNAMIC_TYPE_LITERAL: |
| + return visitor.visitDynamicTypeLiteralPrefix( |
| + node, |
| + 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.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}"); |
| + } |
| +} |
| + |
| + |
| +class PostfixStructure<R, A> implements SendStructure<R, A> { |
| + final AccessSemantics semantics; |
| + final IncDecOperator operator; |
| + final Selector getterSelector; |
| + 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.element, |
| + operator, |
| + arg); |
| + case AccessKind.TYPEDEF_TYPE_LITERAL: |
| + return visitor.visitTypedefTypeLiteralPostfix( |
| + node, |
| + semantics.element, |
| + operator, |
| + arg); |
| + case AccessKind.DYNAMIC_TYPE_LITERAL: |
| + return visitor.visitDynamicTypeLiteralPostfix( |
| + node, |
| + 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.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}"); |
| + } |
| +} |
| + |