| Index: pkg/compiler/lib/src/resolution/send_resolver.dart
|
| diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
|
| index 23ef20c96b0a497c2eacd04a2e5609759426768d..f72f548c330e41be55ca5c269ef96a98c1615a09 100644
|
| --- a/pkg/compiler/lib/src/resolution/send_resolver.dart
|
| +++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
|
| @@ -467,3 +467,309 @@ abstract class SendResolverMixin {
|
| }
|
| }
|
|
|
| +abstract class DeclStructure<R, A> {
|
| + final FunctionElement element;
|
| +
|
| + DeclStructure(this.element);
|
| +
|
| + /// Calls the matching visit method on [visitor] with [node] and [arg].
|
| + R dispatch(SemanticDeclarationVisitor<R, A> visitor,
|
| + FunctionExpression node,
|
| + A arg);
|
| +}
|
| +
|
| +enum ConstructorKind {
|
| + GENERATIVE,
|
| + REDIRECTING_GENERATIVE,
|
| + FACTORY,
|
| + REDIRECTING_FACTORY,
|
| +}
|
| +
|
| +class ConstructorDeclStructure<R, A> extends DeclStructure<R, A> {
|
| + final ConstructorKind kind;
|
| +
|
| + ConstructorDeclStructure(this.kind, ConstructorElement constructor)
|
| + : super(constructor);
|
| +
|
| + R dispatch(SemanticDeclarationVisitor<R, A> visitor,
|
| + FunctionExpression node,
|
| + A arg) {
|
| + switch (kind) {
|
| + case ConstructorKind.GENERATIVE:
|
| + return visitor.visitGenerativeConstructorDeclaration(
|
| + node, element, node.parameters, node.initializers, node.body, arg);
|
| + case ConstructorKind.REDIRECTING_GENERATIVE:
|
| + return visitor.visitRedirectingGenerativeConstructorDeclaration(
|
| + node, element, node.parameters, node.initializers, arg);
|
| + case ConstructorKind.FACTORY:
|
| + return visitor.visitFactoryConstructorDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + default:
|
| + break;
|
| + }
|
| + throw new SpannableAssertionFailure(node,
|
| + "Unhandled constructor declaration kind: ${kind}");
|
| + }
|
| +}
|
| +
|
| +class RedirectingFactoryConstructorDeclStructure<R, A>
|
| + extends DeclStructure<R, A> {
|
| + InterfaceType redirectionTargetType;
|
| + ConstructorElement redirectionTarget;
|
| +
|
| + RedirectingFactoryConstructorDeclStructure(
|
| + ConstructorElement constructor,
|
| + this.redirectionTargetType,
|
| + this.redirectionTarget)
|
| + : super(constructor);
|
| +
|
| + R dispatch(SemanticDeclarationVisitor<R, A> visitor,
|
| + FunctionExpression node,
|
| + A arg) {
|
| + return visitor.visitRedirectingFactoryConstructorDeclaration(
|
| + node, element, node.parameters,
|
| + redirectionTargetType, redirectionTarget, arg);
|
| + }
|
| +}
|
| +
|
| +enum FunctionKind {
|
| + TOP_LEVEL_GETTER,
|
| + TOP_LEVEL_SETTER,
|
| + TOP_LEVEL_FUNCTION,
|
| + STATIC_GETTER,
|
| + STATIC_SETTER,
|
| + STATIC_FUNCTION,
|
| + ABSTRACT_GETTER,
|
| + ABSTRACT_SETTER,
|
| + ABSTRACT_METHOD,
|
| + INSTANCE_GETTER,
|
| + INSTANCE_SETTER,
|
| + INSTANCE_METHOD,
|
| + LOCAL_FUNCTION,
|
| + CLOSURE,
|
| +}
|
| +
|
| +class FunctionDeclStructure<R, A>
|
| + extends DeclStructure<R, A> {
|
| + final FunctionKind kind;
|
| +
|
| + FunctionDeclStructure(this.kind, FunctionElement function)
|
| + : super(function);
|
| +
|
| + R dispatch(SemanticDeclarationVisitor<R, A> visitor,
|
| + FunctionExpression node,
|
| + A arg) {
|
| + switch (kind) {
|
| + case FunctionKind.TOP_LEVEL_GETTER:
|
| + return visitor.visitTopLevelGetterDeclaration(
|
| + node, element, node.body, arg);
|
| + case FunctionKind.TOP_LEVEL_SETTER:
|
| + return visitor.visitTopLevelSetterDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + case FunctionKind.TOP_LEVEL_FUNCTION:
|
| + return visitor.visitTopLevelFunctionDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + case FunctionKind.STATIC_GETTER:
|
| + return visitor.visitStaticGetterDeclaration(
|
| + node, element, node.body, arg);
|
| + case FunctionKind.STATIC_SETTER:
|
| + return visitor.visitStaticSetterDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + case FunctionKind.STATIC_FUNCTION:
|
| + return visitor.visitStaticFunctionDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + case FunctionKind.ABSTRACT_GETTER:
|
| + return visitor.visitAbstractGetterDeclaration(
|
| + node, element, arg);
|
| + case FunctionKind.ABSTRACT_SETTER:
|
| + return visitor.visitAbstractSetterDeclaration(
|
| + node, element, node.parameters, arg);
|
| + case FunctionKind.ABSTRACT_METHOD:
|
| + return visitor.visitAbstractMethodDeclaration(
|
| + node, element, node.parameters, arg);
|
| + case FunctionKind.INSTANCE_GETTER:
|
| + return visitor.visitInstanceGetterDeclaration(
|
| + node, element, node.body, arg);
|
| + case FunctionKind.INSTANCE_SETTER:
|
| + return visitor.visitInstanceSetterDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + case FunctionKind.INSTANCE_METHOD:
|
| + return visitor.visitInstanceMethodDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + case FunctionKind.LOCAL_FUNCTION:
|
| + return visitor.visitLocalFunctionDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + case FunctionKind.CLOSURE:
|
| + return visitor.visitClosureDeclaration(
|
| + node, element, node.parameters, node.body, arg);
|
| + }
|
| + }
|
| +}
|
| +
|
| +abstract class DeclarationResolverMixin {
|
| + TreeElements get elements;
|
| +
|
| + internalError(Spannable spannable, String message);
|
| +
|
| + ConstructorKind computeConstructorKind(ConstructorElement constructor) {
|
| + if (constructor.isRedirectingFactory) {
|
| + return ConstructorKind.REDIRECTING_FACTORY;
|
| + } else if (constructor.isFactoryConstructor) {
|
| + return ConstructorKind.FACTORY;
|
| + } else if (constructor.isRedirectingGenerative) {
|
| + return ConstructorKind.REDIRECTING_GENERATIVE;
|
| + } else {
|
| + return ConstructorKind.GENERATIVE;
|
| + }
|
| + }
|
| +
|
| + DeclStructure computeFunctionStructure(FunctionExpression node) {
|
| + FunctionElement element = elements.getFunctionDefinition(node);
|
| + if (element.isConstructor) {
|
| + ConstructorElement constructor = element;
|
| + ConstructorKind kind = computeConstructorKind(constructor);
|
| + if (kind == ConstructorKind.REDIRECTING_FACTORY) {
|
| + return new RedirectingFactoryConstructorDeclStructure(
|
| + constructor,
|
| + elements.getType(node.body),
|
| + constructor.immediateRedirectionTarget);
|
| + } else {
|
| + return new ConstructorDeclStructure(kind, element);
|
| + }
|
| + } else {
|
| + FunctionKind kind;
|
| + if (element.isLocal) {
|
| + if (element.name.isEmpty) {
|
| + kind = FunctionKind.CLOSURE;
|
| + } else {
|
| + kind = FunctionKind.LOCAL_FUNCTION;
|
| + }
|
| + } else if (element.isInstanceMember) {
|
| + if (element.isGetter) {
|
| + kind = element.isAbstract
|
| + ? FunctionKind.ABSTRACT_GETTER
|
| + : FunctionKind.INSTANCE_GETTER;
|
| + } else if (element.isSetter) {
|
| + kind = element.isAbstract
|
| + ? FunctionKind.ABSTRACT_SETTER
|
| + : FunctionKind.INSTANCE_SETTER;
|
| + } else {
|
| + kind = element.isAbstract
|
| + ? FunctionKind.ABSTRACT_METHOD
|
| + : FunctionKind.INSTANCE_METHOD;
|
| + }
|
| + } else if (element.isStatic) {
|
| + if (element.isGetter) {
|
| + kind = FunctionKind.STATIC_GETTER;
|
| + } else if (element.isSetter) {
|
| + kind = FunctionKind.STATIC_SETTER;
|
| + } else {
|
| + kind = FunctionKind.STATIC_FUNCTION;
|
| + }
|
| + } else if (element.isTopLevel) {
|
| + if (element.isGetter) {
|
| + kind = FunctionKind.TOP_LEVEL_GETTER;
|
| + } else if (element.isSetter) {
|
| + kind = FunctionKind.TOP_LEVEL_SETTER;
|
| + } else {
|
| + kind = FunctionKind.TOP_LEVEL_FUNCTION;
|
| + }
|
| + } else {
|
| + return internalError(node, "Unhandled function expression.");
|
| + }
|
| + return new FunctionDeclStructure(kind, element);
|
| + }
|
| + }
|
| +
|
| + InitializerStructure computeInitializerStructure(Send node) {
|
| + Element element = elements[node];
|
| + if (node.asSendSet() != null) {
|
| + return new FieldInitializerStructure(element);
|
| + } else if (Initializers.isConstructorRedirect(node)) {
|
| + return new ThisConstructorInvokeStructure(
|
| + element, elements.getSelector(node));
|
| + } else if (Initializers.isSuperConstructorCall(node)) {
|
| + return new SuperConstructorInvokeStructure(
|
| + element,
|
| + elements.analyzedElement.enclosingClass.supertype,
|
| + elements.getSelector(node));
|
| + }
|
| + return internalError(node, "Unhandled initializer.");
|
| + }
|
| +
|
| + List<ParameterStructure> computeParameterStructures(NodeList parameters) {
|
| + List<ParameterStructure> list = <ParameterStructure>[];
|
| + int index = 0;
|
| + for (Node node in parameters) {
|
| + NodeList optionalParameters = node.asNodeList();
|
| + if (optionalParameters != null) {
|
| + bool isNamed = optionalParameters.beginToken.stringValue == '{';
|
| + for (Node node in optionalParameters) {
|
| + list.add(computeParameterStructure(
|
| + node, index++, isRequired: false, isNamed: isNamed));
|
| + }
|
| + } else {
|
| + list.add(computeParameterStructure(node, index++));
|
| + }
|
| + }
|
| + return list;
|
| + }
|
| +
|
| + ParameterStructure computeParameterStructure(
|
| + VariableDefinitions definitions,
|
| + int index,
|
| + {bool isRequired: true, bool isNamed: false}) {
|
| + Node node = definitions.definitions.nodes.single;
|
| + ParameterElement element = elements[node];
|
| + if (element == null) {
|
| + throw new SpannableAssertionFailure(
|
| + node, "No parameter structure for $node.");
|
| + }
|
| + if (isRequired) {
|
| + return new RequiredParameterStructure(
|
| + definitions, node, element, index);
|
| + } else {
|
| + ConstantExpression defaultValue;
|
| + if (element.initializer != null) {
|
| + defaultValue = elements.getConstant(element.initializer);
|
| + }
|
| + if (isNamed) {
|
| + return new NamedParameterStructure(
|
| + definitions, node, element, defaultValue);
|
| + } else {
|
| + return new OptionalParameterStructure(
|
| + definitions, node, element, defaultValue, index);
|
| + }
|
| + }
|
| + }
|
| +
|
| + void computeVariableStructures(
|
| + VariableDefinitions definitions,
|
| + void callback(Node node, VariableStructure structure)) {
|
| + for (Node node in definitions.definitions) {
|
| + callback(definitions, computeVariableStructure(node));
|
| + }
|
| + }
|
| +
|
| + VariableStructure computeVariableStructure(Node node) {
|
| + VariableElement element = elements[node];
|
| + VariableKind kind;
|
| + if (element.isLocal) {
|
| + kind = VariableKind.LOCAL_VARIABLE;
|
| + } else if (element.isInstanceMember) {
|
| + kind = VariableKind.INSTANCE_FIELD;
|
| + } else if (element.isStatic) {
|
| + kind = VariableKind.STATIC_FIELD;
|
| + } else if (element.isTopLevel) {
|
| + kind = VariableKind.TOP_LEVEL_FIELD;
|
| + } else {
|
| + return internalError(node, "Unexpected variable $element.");
|
| + }
|
| + if (element.isConst) {
|
| + ConstantExpression constant = elements.getConstant(element.initializer);
|
| + return new ConstantVariableStructure(kind, node, element, constant);
|
| + } else {
|
| + return new NonConstantVariableStructure(kind, node, element);
|
| + }
|
| + }
|
| +}
|
|
|