Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1085)

Unified Diff: pkg/compiler/lib/src/typechecker.dart

Issue 962603002: Typecheck return with respect to async. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Allow return; in generators. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/tree/nodes.dart ('k') | pkg/compiler/lib/src/warnings.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/typechecker.dart
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 321be259fb0d988adbae38aa76c70add76dcf12f..4e861aef086c5e19bebd96f9de478158805d6a85 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -61,7 +61,7 @@ abstract class ElementAccess {
}
}
return compiler.types.isAssignable(
- computeType(compiler), compiler.functionClass.computeType(compiler));
+ computeType(compiler), compiler.coreTypes.functionType);
}
}
@@ -264,6 +264,16 @@ class TypeCheckerVisitor extends Visitor<DartType> {
final ClassElement currentClass;
+ /// The immediately enclosing field, method or constructor being analyzed.
+ ExecutableElement executableContext;
+
+ CoreTypes get coreTypes => compiler.coreTypes;
+
+ InterfaceType get intType => coreTypes.intType;
+ InterfaceType get doubleType => coreTypes.doubleType;
+ InterfaceType get boolType => coreTypes.boolType;
+ InterfaceType get stringType => coreTypes.stringType;
+
DartType thisType;
DartType superType;
@@ -271,13 +281,6 @@ class TypeCheckerVisitor extends Visitor<DartType> {
bool analyzingInitializer = false;
- DartType intType;
- DartType doubleType;
- DartType boolType;
- DartType stringType;
- DartType objectType;
- DartType listType;
-
Map<Node, List<TypePromotion>> shownTypePromotionsMap =
new Map<Node, List<TypePromotion>>();
@@ -337,14 +340,9 @@ class TypeCheckerVisitor extends Visitor<DartType> {
TypeCheckerVisitor(this.compiler, TreeElements elements, this.types)
: this.elements = elements,
- currentClass = elements.analyzedElement != null
+ this.executableContext = elements.analyzedElement,
+ this.currentClass = elements.analyzedElement != null
? elements.analyzedElement.enclosingClass : null {
- intType = compiler.intClass.computeType(compiler);
- doubleType = compiler.doubleClass.computeType(compiler);
- boolType = compiler.boolClass.computeType(compiler);
- stringType = compiler.stringClass.computeType(compiler);
- objectType = compiler.objectClass.computeType(compiler);
- listType = compiler.listClass.computeType(compiler);
if (currentClass != null) {
thisType = currentClass.thisType;
@@ -411,7 +409,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
if (lastSeenNode != null) {
compiler.internalError(lastSeenNode, error);
} else {
- compiler.internalError(elements.analyzedElement, error);
+ compiler.internalError(executableContext, error);
}
} else {
lastSeenNode = node;
@@ -599,8 +597,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
assert(invariant(node, element != null,
message: 'FunctionExpression with no element'));
if (Elements.isUnresolved(element)) return const DynamicType();
- if (identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
- identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR_BODY)) {
+ if (element.isGenerativeConstructor) {
type = const DynamicType();
returnType = const VoidType();
@@ -619,11 +616,16 @@ class TypeCheckerVisitor extends Visitor<DartType> {
returnType = functionType.returnType;
type = functionType;
}
+ ExecutableElement previousExecutableContext = executableContext;
DartType previousReturnType = expectedReturnType;
expectedReturnType = returnType;
AsyncMarker previousAsyncMarker = currentAsyncMarker;
+
+ executableContext = element;
currentAsyncMarker = element.asyncMarker;
analyze(node.body);
+
+ executableContext = previousExecutableContext;
expectedReturnType = previousReturnType;
currentAsyncMarker = previousAsyncMarker;
return type;
@@ -1575,30 +1577,35 @@ class TypeCheckerVisitor extends Visitor<DartType> {
return const StatementType();
}
- final expression = node.expression;
- final isVoidFunction = expectedReturnType.isVoid;
+ final Node expression = node.expression;
// Executing a return statement return e; [...] It is a static type warning
// if the type of e may not be assigned to the declared return type of the
// immediately enclosing function.
if (expression != null) {
- final expressionType = analyze(expression);
- Element element = elements.analyzedElement;
- if (element != null && element.isGenerativeConstructor) {
+ DartType expressionType = analyze(expression);
+ if (executableContext.isGenerativeConstructor) {
// The resolver already emitted an error for this expression.
- } else if (isVoidFunction
- && !types.isAssignable(expressionType, const VoidType())) {
- reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
} else {
- checkAssignable(expression, expressionType, expectedReturnType);
+ switch (currentAsyncMarker) {
+ case AsyncMarker.ASYNC:
floitsch 2015/02/26 15:24:14 No need for a switch.
Johnni Winther 2015/03/02 10:30:58 Done.
+ expressionType = coreTypes.futureType(flatten(expressionType));
+ break;
+ }
+ if (expectedReturnType.isVoid &&
+ !types.isAssignable(expressionType, const VoidType())) {
+ reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
+ } else {
+ checkAssignable(expression, expressionType, expectedReturnType);
+ }
}
- // Let f be the function immediately enclosing a return statement of the
- // form 'return;' It is a static warning if both of the following conditions
- // hold:
- // - f is not a generative constructor.
- // - The return type of f may not be assigned to void.
} else if (!types.isAssignable(expectedReturnType, const VoidType())) {
+ // Let f be the function immediately enclosing a return statement of the
+ // form 'return;' It is a static warning if both of the following
+ // conditions hold:
+ // - f is not a generative constructor.
+ // - The return type of f may not be assigned to void.
reportTypeWarning(node, MessageKind.RETURN_NOTHING,
{'returnType': expectedReturnType});
}
@@ -1622,7 +1629,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
/// return.
DartType flatten(DartType type) {
if (type is InterfaceType) {
- InterfaceType futureType = type.asInstanceOf(compiler.futureClass);
+ InterfaceType futureType = type.asInstanceOf(coreTypes.futureClass);
if (futureType != null) {
return flatten(futureType.typeArguments.first);
}
@@ -1639,17 +1646,17 @@ class TypeCheckerVisitor extends Visitor<DartType> {
DartType resultType = analyze(node.expression);
if (!node.hasStar) {
if (currentAsyncMarker.isAsync) {
- resultType = compiler.coreTypes.streamType(resultType);
+ resultType = coreTypes.streamType(resultType);
} else {
- resultType = compiler.coreTypes.iterableType(resultType);
+ resultType = coreTypes.iterableType(resultType);
}
} else {
if (currentAsyncMarker.isAsync) {
// The static type of expression must be assignable to Stream.
- checkAssignable(node, resultType, compiler.coreTypes.streamType());
+ checkAssignable(node, resultType, coreTypes.streamType());
} else {
// The static type of expression must be assignable to Iterable.
- checkAssignable(node, resultType, compiler.coreTypes.iterableType());
+ checkAssignable(node, resultType, coreTypes.iterableType());
}
}
// The static type of the result must be assignable to the declared type.
@@ -1706,7 +1713,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
DartType thenType = analyzeInPromotedContext(condition, thenExpression);
DartType elseType = analyze(node.elseExpression);
- return compiler.types.computeLeastUpperBound(thenType, elseType);
+ return types.computeLeastUpperBound(thenType, elseType);
}
visitStringInterpolation(StringInterpolation node) {
@@ -1792,8 +1799,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
}
if (!hasDefaultCase && expressionType.isEnumType) {
- compiler.enqueuer.resolution.addDeferredAction(
- elements.analyzedElement, () {
+ compiler.enqueuer.resolution.addDeferredAction(executableContext, () {
Map<ConstantValue, FieldElement> enumValues =
<ConstantValue, FieldElement>{};
List<FieldElement> unreferencedFields = <FieldElement>[];
« no previous file with comments | « pkg/compiler/lib/src/tree/nodes.dart ('k') | pkg/compiler/lib/src/warnings.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698