| Index: pkg/compiler/lib/src/resolution/members.dart
|
| diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
|
| index 53579c3a11c96af4b1e00a3d8a8e526d7f77db09..61011b60178eb4c793dacad38fb70dd09fc4fa15 100644
|
| --- a/pkg/compiler/lib/src/resolution/members.dart
|
| +++ b/pkg/compiler/lib/src/resolution/members.dart
|
| @@ -540,7 +540,9 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
| Element target;
|
| String name = node.selector.asIdentifier().source;
|
| if (identical(name, 'this')) {
|
| - error(node.selector, MessageKind.THIS_PROPERTY);
|
| + // TODO(ahe): Why is this using GENERIC?
|
| + error(node.selector, MessageKind.GENERIC,
|
| + {'text': "expected an identifier"});
|
| return const NoneResult();
|
| } else if (node.isSuperCall) {
|
| if (node.isOperator) {
|
| @@ -955,7 +957,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
| return computeSuperAccessSemantics(node, target);
|
| }
|
|
|
| - /// Resolve [node] as a subexpression that is _not_ the prefix of a member
|
| + /// Resolve [node] as subexpression that is _not_ the prefix of a member
|
| /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
|
| ResolutionResult visitExpression(Node node) {
|
| bool oldSendIsMemberAccess = sendIsMemberAccess;
|
| @@ -965,39 +967,6 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
| return result;
|
| }
|
|
|
| - /// Resolve [node] as a subexpression that _is_ the prefix of a member access.
|
| - /// For instance `a` in `a.b`, as opposed to `a` in `a + b`.
|
| - ResolutionResult visitExpressionPrefix(Node node) {
|
| - int oldAllowedCategory = allowedCategory;
|
| - bool oldSendIsMemberAccess = sendIsMemberAccess;
|
| - allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
|
| - sendIsMemberAccess = true;
|
| - ResolutionResult result = visit(node);
|
| - sendIsMemberAccess = oldSendIsMemberAccess;
|
| - allowedCategory = oldAllowedCategory;
|
| - return result;
|
| - }
|
| -
|
| - /// Resolved [node] as a subexpression that is the prefix of a conditional
|
| - /// access. For instance `a` in `a?.b`.
|
| - // TODO(johnniwinther): Is this equivalent to [visitExpression]?
|
| - ResolutionResult visitConditionalPrefix(Node node) {
|
| - // Conditional sends like `e?.foo` treat the receiver as an expression. So
|
| - // `C?.foo` needs to be treated like `(C).foo`, not like C.foo. Prefixes and
|
| - // super are not allowed on their own in that context.
|
| - int oldAllowedCategory = allowedCategory;
|
| - bool oldSendIsMemberAccess = sendIsMemberAccess;
|
| - sendIsMemberAccess = false;
|
| - allowedCategory =
|
| - ElementCategory.VARIABLE |
|
| - ElementCategory.FUNCTION |
|
| - ElementCategory.IMPLIES_TYPE;
|
| - ResolutionResult result = visit(node);
|
| - sendIsMemberAccess = oldSendIsMemberAccess;
|
| - allowedCategory = oldAllowedCategory;
|
| - return result;
|
| - }
|
| -
|
| /// Handle a type test expression, like `a is T` and `a is! T`.
|
| ResolutionResult handleIs(Send node) {
|
| Node expression = node.receiver;
|
| @@ -1420,8 +1389,26 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
| /// Handle access of a property of [name] on `this`, like `this.name` and
|
| /// `this.name()`, or `name` and `name()` in instance context.
|
| ResolutionResult handleThisPropertyAccess(Send node, Name name) {
|
| - AccessSemantics semantics = new AccessSemantics.thisProperty();
|
| - return handleDynamicAccessSemantics(node, name, semantics);
|
| + AccessSemantics accessSemantics = new AccessSemantics.thisProperty();
|
| + SendStructure sendStructure;
|
| + Selector selector;
|
| + if (node.isCall) {
|
| + CallStructure callStructure = resolveArguments(node.argumentsNode);
|
| + selector = new Selector(SelectorKind.CALL, name, callStructure);
|
| + registry.registerDynamicInvocation(selector);
|
| + sendStructure = new InvokeStructure(accessSemantics, selector);
|
| + } else {
|
| + assert(invariant(node, node.isPropertyAccess));
|
| + selector = new Selector(
|
| + SelectorKind.GETTER, name, CallStructure.NO_ARGS);
|
| + registry.registerDynamicGetter(selector);
|
| + sendStructure = new GetStructure(accessSemantics, selector);
|
| + }
|
| + registry.registerSendStructure(node, sendStructure);
|
| + // TODO(johnniwinther): Remove this when all information goes through
|
| + // the [SendStructure].
|
| + registry.setSelector(node, selector);
|
| + return const NoneResult();
|
| }
|
|
|
| /// Handle access on `this`, like `this()` and `this` when it is parsed as a
|
| @@ -1589,177 +1576,12 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
| }
|
| }
|
|
|
| - /// Handle qualified access to an unresolved static class member, like `a.b`
|
| - /// or `a.b()` where `a` is a class and `b` is unresolved.
|
| - ResolutionResult handleUnresolvedStaticMemberAccess(
|
| - Send node, Name name, ClassElement receiverClass) {
|
| - // TODO(johnniwinther): Share code with [handleStaticInstanceMemberAccess]
|
| - // and [handlePrivateStaticMemberAccess].
|
| - registry.registerThrowNoSuchMethod();
|
| - // TODO(johnniwinther): Produce a different error if [name] is resolves to
|
| - // a constructor.
|
| -
|
| - // TODO(johnniwinther): With the simplified [TreeElements] invariant,
|
| - // try to resolve injected elements if [currentClass] is in the patch
|
| - // library of [receiverClass].
|
| -
|
| - // TODO(karlklose): this should be reported by the caller of
|
| - // [resolveSend] to select better warning messages for getters and
|
| - // setters.
|
| - ErroneousElement error = reportAndCreateErroneousElement(
|
| - node, name.text, MessageKind.MEMBER_NOT_FOUND,
|
| - {'className': receiverClass.name, 'memberName': name.text});
|
| - // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
|
| - // member access.
|
| - return handleErroneousAccess(
|
| - node, name, error, new StaticAccess.unresolved(error));
|
| - }
|
| -
|
| - /// Handle qualified access of an instance member, like `a.b` or `a.b()` where
|
| - /// `a` is a class and `b` is a non-static member.
|
| - ResolutionResult handleStaticInstanceMemberAccess(
|
| - Send node, Name name, ClassElement receiverClass, Element member) {
|
| -
|
| - registry.registerThrowNoSuchMethod();
|
| - // TODO(johnniwinther): With the simplified [TreeElements] invariant,
|
| - // try to resolve injected elements if [currentClass] is in the patch
|
| - // library of [receiverClass].
|
| -
|
| - // TODO(karlklose): this should be reported by the caller of
|
| - // [resolveSend] to select better warning messages for getters and
|
| - // setters.
|
| - ErroneousElement error = reportAndCreateErroneousElement(
|
| - node, name.text, MessageKind.MEMBER_NOT_STATIC,
|
| - {'className': receiverClass.name, 'memberName': name});
|
| -
|
| - // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed
|
| - // instance members.
|
| - return handleErroneousAccess(
|
| - node, name, error, new StaticAccess.unresolved(error));
|
| - }
|
| -
|
| - /// Handle qualified access of an inaccessible private static class member,
|
| - /// like `a._b` or `a.b()` where `a` is class, `_b` is static member of `a`
|
| - /// but `a` is not defined in the current library.
|
| - ResolutionResult handlePrivateStaticMemberAccess(
|
| - Send node, Name name, ClassElement receiverClass, Element member) {
|
| - registry.registerThrowNoSuchMethod();
|
| - ErroneousElement error = reportAndCreateErroneousElement(
|
| - node, name.text, MessageKind.PRIVATE_ACCESS,
|
| - {'libraryName': member.library.getLibraryOrScriptName(),
|
| - 'name': name});
|
| - // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
|
| - // member access.
|
| - return handleErroneousAccess(
|
| - node, name, error, new StaticAccess.unresolved(error));
|
| - }
|
| -
|
| - /// Handle qualified access to a static member, like `a.b` or `a.b()` where
|
| - /// `a` is a class and `b` is a static member of `a`.
|
| - ResolutionResult handleStaticMemberAccess(
|
| - Send node, Name memberName, ClassElement receiverClass) {
|
| - String name = memberName.text;
|
| - receiverClass.ensureResolved(compiler);
|
| - if (node.isOperator) {
|
| - // When the resolved receiver is a class, we can have two cases:
|
| - // 1) a static send: C.foo, or
|
| - // 2) an operator send, where the receiver is a class literal: 'C + 1'.
|
| - // The following code that looks up the selector on the resolved
|
| - // receiver will treat the second as the invocation of a static operator
|
| - // if the resolved receiver is not null.
|
| - return const NoneResult();
|
| - }
|
| - MembersCreator.computeClassMembersByName(
|
| - compiler, receiverClass.declaration, name);
|
| - Element member = receiverClass.lookupLocalMember(name);
|
| - if (member == null) {
|
| - return handleUnresolvedStaticMemberAccess(
|
| - node, memberName, receiverClass);
|
| - } else if (member.isInstanceMember) {
|
| - return handleStaticInstanceMemberAccess(
|
| - node, memberName, receiverClass, member);
|
| - } else if (memberName.isPrivate && memberName.library != member.library) {
|
| - return handlePrivateStaticMemberAccess(
|
| - node, memberName, receiverClass, member);
|
| - } else {
|
| - return handleStaticOrTopLevelAccess(node, memberName, member);
|
| - }
|
| - }
|
| -
|
| - /// Handle qualified [Send] where the receiver resolves to an [Element], like
|
| - /// `a.b` where `a` is a local, field, class, or prefix, etc.
|
| - ResolutionResult handleResolvedQualifiedSend(
|
| - Send node, Name name, Element element) {
|
| - if (element.isPrefix) {
|
| - return oldVisitSend(node);
|
| - } else if (element.isClass) {
|
| - return handleStaticMemberAccess(node, name, element);
|
| - }
|
| - return oldVisitSend(node);
|
| - }
|
| -
|
| - /// Handle dynamic access of [semantics].
|
| - ResolutionResult handleDynamicAccessSemantics(
|
| - Send node, Name name, AccessSemantics semantics) {
|
| - SendStructure sendStructure;
|
| - Selector selector;
|
| - if (node.isCall) {
|
| - CallStructure callStructure = resolveArguments(node.argumentsNode);
|
| - selector = new Selector(SelectorKind.CALL, name, callStructure);
|
| - registry.registerDynamicInvocation(selector);
|
| - sendStructure = new InvokeStructure(semantics, selector);
|
| - } else {
|
| - assert(invariant(node, node.isPropertyAccess));
|
| - selector = new Selector(
|
| - SelectorKind.GETTER, name, CallStructure.NO_ARGS);
|
| - registry.registerDynamicGetter(selector);
|
| - sendStructure = new GetStructure(semantics, selector);
|
| - }
|
| - registry.registerSendStructure(node, sendStructure);
|
| - // TODO(johnniwinther): Remove this when all information goes through
|
| - // the [SendStructure].
|
| - registry.setSelector(node, selector);
|
| - return const NoneResult();
|
| - }
|
| -
|
| - /// Handle dynamic property access, like `a.b` or `a.b()` where `a` is not a
|
| - /// prefix or class.
|
| - ResolutionResult handleDynamicPropertyAccess(Send node, Name name) {
|
| - AccessSemantics semantics =
|
| - new DynamicAccess.dynamicProperty(node.receiver);
|
| - return handleDynamicAccessSemantics(node, name, semantics);
|
| - }
|
| -
|
| - /// Handle conditional access, like `a?.b` or `a?.b()`.
|
| - ResolutionResult handleConditionalAccess(Send node, Name name) {
|
| - Node receiver = node.receiver;
|
| - visitConditionalPrefix(receiver);
|
| - AccessSemantics semantics =
|
| - new DynamicAccess.ifNotNullProperty(receiver);
|
| - return handleDynamicAccessSemantics(node, name, semantics);
|
| - }
|
| -
|
| - /// Handle `this` as a qualified property, like `a.this`.
|
| - ResolutionResult handleQualifiedThisAccess(Send node, Name name) {
|
| - ErroneousElement error = reportAndCreateErroneousElement(
|
| - node.selector,
|
| - name.text,
|
| - MessageKind.THIS_PROPERTY, {},
|
| - isError: true);
|
| - // TODO(johnniwinther): Support `this` as property as an [AccessSemantics].
|
| - AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
|
| - return handleErroneousAccess(node, name, error, accessSemantics);
|
| - }
|
| -
|
| /// Handle a qualified [Send], that is where the receiver is non-null, like
|
| /// `a.b`, `a.b()`, `this.a()` and `super.a()`.
|
| ResolutionResult handleQualifiedSend(Send node) {
|
| Identifier selector = node.selector.asIdentifier();
|
| - String text = selector.source;
|
| - Name name = new Name(text, enclosingElement.library);
|
| - if (text == 'this') {
|
| - return handleQualifiedThisAccess(node, name);
|
| - } else if (node.isSuperCall) {
|
| + Name name = new Name(selector.source, enclosingElement.library);
|
| + if (node.isSuperCall) {
|
| return handleSuperPropertyAccess(node, name);
|
| } else if (node.receiver.isThis()) {
|
| if (checkThisAccess(node)) {
|
| @@ -1768,15 +1590,9 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
| // TODO(johnniwinther): Handle invalid this access as an
|
| // [AccessSemantics].
|
| return const NoneResult();
|
| - } else if (node.isConditional) {
|
| - return handleConditionalAccess(node, name);
|
| - }
|
| - ResolutionResult result = visitExpressionPrefix(node.receiver);
|
| - if (result.element != null) {
|
| - return handleResolvedQualifiedSend(node, name, result.element);
|
| - } else {
|
| - return handleDynamicPropertyAccess(node, name);
|
| }
|
| + // TODO(johnniwinther): Handle remaining qualified sends.
|
| + return oldVisitSend(node);
|
| }
|
|
|
| /// Handle access unresolved access to [name] in a non-instance context.
|
| @@ -2648,10 +2464,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
| bool oldSendIsMemberAccess = sendIsMemberAccess;
|
| sendIsMemberAccess = false;
|
| var oldCategory = allowedCategory;
|
| - allowedCategory =
|
| - ElementCategory.VARIABLE |
|
| - ElementCategory.FUNCTION |
|
| - ElementCategory.IMPLIES_TYPE;
|
| + allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
|
| + | ElementCategory.IMPLIES_TYPE;
|
| ResolutionResult result = visit(node.expression);
|
| allowedCategory = oldCategory;
|
| sendIsMemberAccess = oldSendIsMemberAccess;
|
|
|