Index: lib/compiler/implementation/resolution/members.dart |
diff --git a/lib/compiler/implementation/resolution/members.dart b/lib/compiler/implementation/resolution/members.dart |
index f96bf11e786cad256e730dae6ca0b7deb1a6d68f..2f79c0cd536da9eeef2b6c1f14244afcd81af69a 100644 |
--- a/lib/compiler/implementation/resolution/members.dart |
+++ b/lib/compiler/implementation/resolution/members.dart |
@@ -1176,7 +1176,8 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
ExpressionStatement currentExpressionStatement; |
bool typeRequired = false; |
StatementScope statementScope; |
- int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; |
+ int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
+ | ElementCategory.IMPLIES_TYPE; |
ResolverVisitor(Compiler compiler, Element element, this.mapping) |
: this.enclosingElement = element, |
@@ -1281,6 +1282,11 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
error(node, MessageKind.GENERIC, ["is not an expression $element"]); |
} |
} |
+ if (!Elements.isUnresolved(element) |
+ && element.kind == ElementKind.CLASS) { |
+ ClassElement classElement = element; |
+ classElement.ensureResolved(compiler); |
+ } |
return useElement(node, element); |
} |
} |
@@ -1506,12 +1512,12 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
return compiler.assertMethod; |
} |
+ |
return node.selector.accept(this); |
} |
var oldCategory = allowedCategory; |
- allowedCategory |= |
- ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER; |
+ allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; |
Element resolvedReceiver = visit(node.receiver); |
allowedCategory = oldCategory; |
@@ -1546,6 +1552,15 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} else if (identical(resolvedReceiver.kind, ElementKind.CLASS)) { |
ClassElement receiverClass = resolvedReceiver; |
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 null; |
+ } |
target = receiverClass.lookupLocalMember(name); |
if (target == null) { |
// TODO(johnniwinther): With the simplified [TreeElements] invariant, |
@@ -1564,10 +1579,13 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { |
PrefixElement prefix = resolvedReceiver; |
target = prefix.lookupLocalMember(name); |
- if (target == null) { |
+ if (Elements.isUnresolved(target)) { |
return warnAndCreateErroneousElement( |
node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
[prefix.name, name]); |
+ } else if (target.kind == ElementKind.CLASS) { |
+ ClassElement classElement = target; |
+ classElement.ensureResolved(compiler); |
} |
} |
return target; |
@@ -1707,6 +1725,10 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
// with the same arguments. |
Selector call = new Selector.callClosureFrom(selector); |
world.registerDynamicInvocation(call.name, call); |
+ } else if (target.impliesType()) { |
+ // We call 'call()' on a Type instance returned from the reference to a |
+ // class or typedef literal. We do not need to register this call as a |
+ // dynamic invocation, because we statically know what the target is. |
} else if (!selector.applies(target, compiler)) { |
warnArgumentMismatch(node, target); |
} |