herhut@google.com 2015-03-19 13:21:29 +00:00
parent f7c7707d35
commit 34b6869777
7 changed files with 64 additions and 2 deletions

View file

@ -2243,6 +2243,11 @@ class ConcreteTypesInferrer
return result;
}
ConcreteType registerAwait(Node node, ConcreteType argumentType) {
// TODO(polux): Properly handle await expressions.
return types.dynamicType;
}
@override
void setDefaultTypeOfParameter(ParameterElement parameter,
ConcreteType type) {

View file

@ -144,6 +144,10 @@ abstract class TracerVisitor<T extends TypeInformation>
continueAnalyzing = false;
}
void visitAwaitTypeInformation(AwaitTypeInformation info) {
bailout("Passed through await");
}
void visitNarrowTypeInformation(NarrowTypeInformation info) {
addNewEscapeInformation(info);
}

View file

@ -280,6 +280,12 @@ abstract class InferrerEngine<T, V extends TypeSystem>
SideEffects sideEffects,
bool inLoop);
/**
* Registers a call to await with an expression of type [argumentType] as
* argument.
*/
T registerAwait(ast.Node node, T argumentType);
/**
* Notifies to the inferrer that [analyzedElement] can have return
* type [newType]. [currentType] is the type the [InferrerVisitor]
@ -1011,8 +1017,7 @@ class SimpleTypeInferrerVisitor<T>
T visitAwait(ast.Await node) {
T futureType = node.expression.accept(this);
// TODO(herhut): Return a better type here if possible.
return types.dynamicType;
return inferrer.registerAwait(node, futureType);
}
T visitStaticSend(ast.Send node) {

View file

@ -1128,6 +1128,14 @@ class TypeGraphInferrerEngine
return info;
}
TypeInformation registerAwait(ast.Node node, TypeInformation argument) {
AwaitTypeInformation info = new AwaitTypeInformation(types.currentMember,
node);
info.addAssignment(argument);
types.allocatedTypes.add(info);
return info;
}
TypeInformation registerCalledClosure(ast.Node node,
Selector selector,
TypeInformation closure,

View file

@ -1518,6 +1518,22 @@ abstract class TracedTypeInformation implements TypeInformation {
}
}
class AwaitTypeInformation extends TypeInformation {
final ast.Node node;
AwaitTypeInformation(MemberTypeInformation context, this.node)
: super(context);
// TODO(22894): Compute a better type here.
TypeMask computeType(TypeGraphInferrerEngine inferrer) => safeType(inferrer);
String toString() => 'Await';
accept(TypeInformationVisitor visitor) {
return visitor.visitAwaitTypeInformation(this);
}
}
abstract class TypeInformationVisitor<T> {
T visitNarrowTypeInformation(NarrowTypeInformation info);
T visitPhiElementTypeInformation(PhiElementTypeInformation info);
@ -1535,4 +1551,5 @@ abstract class TypeInformationVisitor<T> {
T visitMemberTypeInformation(MemberTypeInformation info);
T visitParameterTypeInformation(ParameterTypeInformation info);
T visitClosureTypeInformation(ClosureTypeInformation info);
T visitAwaitTypeInformation(AwaitTypeInformation info);
}

View file

@ -0,0 +1,12 @@
// Copyright (c) 2015, 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.
// Regression test for http://dartbug.com/22868/
// Ensure that the closure tracer properly handles await.
main() async {
var closures = [(x, y) => x + y];
print(((await closures)[0])(4, 2));
}

View file

@ -0,0 +1,11 @@
// Copyright (c) 2015, 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.
// Regression test for http://dartbug.com/22895/
// Ensure that the type graph is retained in presence of await.
main() async {
var closures = [(x, y) => x + y];
print(((await closures)[0])(4, 2));
}