| Index: pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| index 086edfbec59ad5e6e62b0ee33f3bd9b2c7828370..21558f093da9fb4501abc9e36d1b60630a97cdfd 100644
|
| --- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| +++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| @@ -120,6 +120,9 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
|
| TypeMask get constMapType => compiler.typesTask.constMapType;
|
| TypeMask get stringType => compiler.typesTask.stringType;
|
| TypeMask get typeType => compiler.typesTask.typeType;
|
| + TypeMask get syncStarIterableType => compiler.typesTask.syncStarIterableType;
|
| + TypeMask get asyncFutureType => compiler.typesTask.asyncFutureType;
|
| + TypeMask get asyncStarStreamType => compiler.typesTask.asyncStarStreamType;
|
| bool isNull(TypeMask mask) => mask.isEmpty && mask.isNullable;
|
|
|
| TypeMask stringLiteralType(ast.DartString value) => stringType;
|
| @@ -650,21 +653,37 @@ class SimpleTypeInferrerVisitor<T>
|
| locals.update(element, inferrer.typeOfElement(element), node);
|
| });
|
| visit(node.body);
|
| - if (function.asyncMarker != AsyncMarker.SYNC) {
|
| - // TODO(herhut): Should be type Future/Iterable/Stream instead of
|
| - // dynamic.
|
| - returnType = inferrer.addReturnTypeFor(
|
| - analyzedElement, returnType, types.dynamicType);
|
| - } else if (returnType == null) {
|
| - // No return in the body.
|
| - returnType = locals.seenReturnOrThrow
|
| - ? types.nonNullEmpty() // Body always throws.
|
| - : types.nullType;
|
| - } else if (!locals.seenReturnOrThrow) {
|
| - // We haven't seen returns on all branches. So the method may
|
| - // also return null.
|
| - returnType = inferrer.addReturnTypeFor(
|
| - analyzedElement, returnType, types.nullType);
|
| + switch (function.asyncMarker) {
|
| + case AsyncMarker.SYNC:
|
| + if (returnType == null) {
|
| + // No return in the body.
|
| + returnType = locals.seenReturnOrThrow
|
| + ? types.nonNullEmpty() // Body always throws.
|
| + : types.nullType;
|
| + } else if (!locals.seenReturnOrThrow) {
|
| + // We haven't seen returns on all branches. So the method may
|
| + // also return null.
|
| + returnType = inferrer.addReturnTypeFor(
|
| + analyzedElement, returnType, types.nullType);
|
| + }
|
| + break;
|
| +
|
| + case AsyncMarker.SYNC_STAR:
|
| + // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
|
| + // contained is the method body's return type.
|
| + returnType = inferrer.addReturnTypeFor(
|
| + analyzedElement, returnType, types.syncStarIterableType);
|
| + break;
|
| +
|
| + case AsyncMarker.ASYNC:
|
| + returnType = inferrer.addReturnTypeFor(
|
| + analyzedElement, returnType, types.asyncFutureType);
|
| + break;
|
| +
|
| + case AsyncMarker.ASYNC_STAR:
|
| + returnType = inferrer.addReturnTypeFor(
|
| + analyzedElement, returnType, types.asyncStarStreamType);
|
| + break;
|
| }
|
| }
|
|
|
|
|