Do not infer types of arguments of closures and methods named "call".

R=ahe@google.com

Review URL: https://codereview.chromium.org//14260012

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@22109 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
ngeoffray@google.com 2013-04-29 10:38:46 +00:00
parent a3a72271ec
commit f341cacd45
4 changed files with 37 additions and 9 deletions

View file

@ -1079,7 +1079,7 @@ class InitializerResolver {
// Resolve the selector and the arguments.
ResolverTask resolver = visitor.compiler.resolver;
visitor.inStaticContext(() {
visitor.resolveSelector(call);
visitor.resolveSelector(call, null);
visitor.resolveArguments(call.argumentsNode);
});
Selector selector = visitor.mapping.getSelector(call);
@ -1997,7 +1997,7 @@ class ResolverVisitor extends MappingVisitor<Element> {
}
Element resolveSend(Send node) {
Selector selector = resolveSelector(node);
Selector selector = resolveSelector(node, null);
if (node.isSuperCall) mapping.superUses.add(node);
if (node.receiver == null) {
@ -2120,7 +2120,9 @@ class ResolverVisitor extends MappingVisitor<Element> {
return resolveTypeRequired(node);
}
static Selector computeSendSelector(Send node, LibraryElement library) {
static Selector computeSendSelector(Send node,
LibraryElement library,
Element element) {
// First determine if this is part of an assignment.
bool isSet = node.asSendSet() != null;
@ -2169,15 +2171,20 @@ class ResolverVisitor extends MappingVisitor<Element> {
arity++;
}
if (element != null && element.isConstructor()) {
return new Selector.callConstructor(
element.name, library, arity, named);
}
// If we're invoking a closure, we do not have an identifier.
return (identifier == null)
? new Selector.callClosure(arity, named)
: new Selector.call(identifier.source, library, arity, named);
}
Selector resolveSelector(Send node) {
Selector resolveSelector(Send node, Element element) {
LibraryElement library = enclosingElement.getLibrary();
Selector selector = computeSendSelector(node, library);
Selector selector = computeSendSelector(node, library, element);
if (selector != null) mapping.setSelector(node, selector);
return selector;
}
@ -2558,7 +2565,7 @@ class ResolverVisitor extends MappingVisitor<Element> {
node.newToken, MessageKind.NON_CONST_BLOAT,
{'name': compiler.symbolClass.name});
}
resolveSelector(node.send);
resolveSelector(node.send, constructor);
resolveArguments(node.send.argumentsNode);
useElement(node.send, constructor);
if (Elements.isUnresolved(constructor)) return constructor;

View file

@ -829,6 +829,11 @@ class InternalSimpleTypesInferrer extends TypesInferrer {
ArgumentsTypes arguments,
Selector constraint,
bool inLoop) {
// Bailout for closure calls. We're not tracking types of
// arguments for closures.
if (callee.isInstanceMember() && selector.isClosureCall()) {
return;
}
if (inLoop) {
// For instance methods, we only register a selector called in a
// loop if it is a typed selector, to avoid marking too many

View file

@ -175,12 +175,14 @@ class Selector {
selector.argumentCount, selector.namedArguments);
Selector.callConstructor(SourceString constructorName,
LibraryElement library)
LibraryElement library,
[int arity = 0,
List<SourceString> named = const []])
: this(SelectorKind.CALL,
constructorName,
library,
0,
const []);
arity,
named);
Selector.callDefaultConstructor(LibraryElement library)
: this(SelectorKind.CALL, const SourceString(""), library, 0, const []);

View file

@ -0,0 +1,14 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
class A {
call(a) => a is num;
}
main() {
Expect.isTrue(new A().call(42));
Expect.isFalse(new A()('foo'));
}