Chromium Code Reviews| Index: lib/compiler/implementation/resolver.dart |
| diff --git a/lib/compiler/implementation/resolver.dart b/lib/compiler/implementation/resolver.dart |
| index d08b6f60ca5ce0cc308a54015c56b5e351805294..1251188eb7d20751adb28d23635ea899a62fb904 100644 |
| --- a/lib/compiler/implementation/resolver.dart |
| +++ b/lib/compiler/implementation/resolver.dart |
| @@ -1413,10 +1413,16 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| } |
| Element resolveSend(Send node) { |
| - Selector selector = resolveSelector(node); |
| + void withAdditionalCategories(int categories, void f()) { |
| + var oldCategory = allowedCategory; |
| + allowedCategory |= categories; |
| + f(); |
| + allowedCategory = oldCategory; |
| + } |
| + Selector selector = resolveSelector(node); |
| if (node.receiver === null) { |
| - // If this send is the expression of an expression statement, and is on |
| + // If this send is the expression of an expression statement, and is of |
| // the form "assert(expr);", and there is no declaration with name |
| // "assert" in the lexical scope, then this is actually an assertion. |
| if (isExpressionStatementExpression(node) && |
| @@ -1424,14 +1430,29 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| !isAssertInLexicalScope()) { |
| return compiler.assertMethod; |
| } |
| - return node.selector.accept(this); |
| + |
| + Element result; |
| + withAdditionalCategories(ElementCategory.CLASS, () { |
| + result = node.selector.accept(this); |
| + }); |
| + return result; |
| } |
| - var oldCategory = allowedCategory; |
| - allowedCategory |= |
| - ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER; |
| - Element resolvedReceiver = visit(node.receiver); |
| - allowedCategory = oldCategory; |
| + Element resolvedReceiver; |
| + withAdditionalCategories( |
| + ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER, |
| + () { resolvedReceiver = visit(node.receiver); }); |
| + |
| + if (resolvedReceiver != null && node.isOperator |
|
ahe
2012/10/08 09:09:36
I don't understand why it is important to test for
karlklose
2012/10/23 10:33:52
For class literals that are targets for operators,
|
| + && resolvedReceiver.kind == ElementKind.CLASS) { |
| + // In operator expressions like 'Class + 1', the operator call goes the |
| + // instance of [Type] that is the result of the expression 'Class'. |
| + ClassElement classElement = resolvedReceiver; |
| + resolvedReceiver = null; |
| + // We still have to make sure that the class is resolved, because we need |
| + // to build its runtime type representation. |
| + classElement.ensureResolved(compiler); |
| + } |
| Element target; |
| SourceString name = node.selector.asIdentifier().source; |
| @@ -1522,7 +1543,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| } |
| Identifier identifier = node.selector.asIdentifier(); |
| - if (node.isPropertyAccess) { |
| + if (node.isPropertyAccessOrTypeReference) { |
| assert(!isSet); |
| return new Selector.getter(identifier.source, library); |
| } else if (isSet) { |
| @@ -1572,15 +1593,20 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| visitSend(Send node) { |
| Element target = resolveSend(node); |
| - if (!Elements.isUnresolved(target) |
| - && target.kind == ElementKind.ABSTRACT_FIELD) { |
| - AbstractFieldElement field = target; |
| - target = field.getter; |
| - if (target == null && !inInstanceContext) { |
| - target = |
| - warnAndCreateErroneousElement(node.selector, field.name, |
| - MessageKind.CANNOT_RESOLVE_GETTER, |
| - [node.selector]); |
| + |
| + if (!Elements.isUnresolved(target)) { |
| + if (target.kind == ElementKind.ABSTRACT_FIELD) { |
| + AbstractFieldElement field = target; |
| + target = field.getter; |
| + if (target == null && !inInstanceContext) { |
| + target = |
| + warnAndCreateErroneousElement(node.selector, field.name, |
| + MessageKind.CANNOT_RESOLVE_GETTER, |
| + [node.selector]); |
| + } |
| + } else if (target.kind == ElementKind.CLASS) { |
| + ClassElement classElement = target; |
| + classElement.ensureResolved(compiler); |
|
ahe
2012/10/08 09:09:36
Why is this not done in resolveSend?
karlklose
2012/10/23 10:33:52
Moved.
|
| } |
| } |
| @@ -1628,11 +1654,15 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| // unqualified. |
| useElement(node, target); |
| registerSend(selector, target); |
| - return node.isPropertyAccess ? target : null; |
| + return node.isPropertyAccessOrTypeReference ? target : null; |
| } |
| visitSendSet(SendSet node) { |
| Element target = resolveSend(node); |
| + if (!Elements.isUnresolved(target) && target.kind == ElementKind.CLASS) { |
| + ClassElement classElement = target; |
| + classElement.ensureResolved(compiler); |
|
ahe
2012/10/08 09:09:36
Why is this not done in resolveSend?
karlklose
2012/10/23 10:33:52
Done.
|
| + } |
| Element setter = target; |
| Element getter = target; |
| SourceString operatorName = node.assignmentOperator.source; |