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; |