Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (revision 22743) |
| +++ sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (working copy) |
| @@ -113,6 +113,10 @@ |
| throw 'Unsupported operation'; |
| } |
| + TypeMask intersection(TypeMask other, Compiler compiler) { |
| + return other; |
| + } |
| + |
| bool get isNullable => true; |
| String toString() => '$name sentinel type mask'; |
| @@ -649,6 +653,15 @@ |
| bool internalRecordType(Element analyzedElement, |
| TypeMask newType, |
| Map<Element, TypeMask> types) { |
| + if (compiler.trustTypeAnnotations) { |
| + var annotation = analyzedElement.computeType(compiler); |
| + if (types == returnTypeOf) { |
| + assert(annotation is FunctionType); |
| + annotation = annotation.returnType; |
| + } |
| + newType = narrowType(newType, annotation); |
| + } |
| + |
| // Fields and native methods of native classes are handled |
| // specially when querying for their type or return type. |
| if (isNativeElement(analyzedElement)) return false; |
| @@ -684,7 +697,15 @@ |
| } |
| TypeMask returnType = returnTypeOf[element]; |
| if (returnType == null) { |
| - return dynamicType; |
| + if (compiler.trustTypeAnnotations |
| + && (element.isFunction() |
| + || element.isGetter() |
| + || element.isFactoryConstructor())) { |
| + returnType = narrowType( |
|
kasperl
2013/05/16 13:17:20
Couldn't you do the narrowing when you record? (li
ngeoffray
2013/05/17 14:34:25
This is in case the element has not been analyzed
|
| + dynamicType, element.computeType(compiler).returnType); |
| + } else { |
| + returnType = dynamicType; |
| + } |
| } |
| assert(returnType != null); |
| return returnType; |
| @@ -749,7 +770,13 @@ |
| } |
| TypeMask type = typeOf[element]; |
| if (type == null) { |
| - return dynamicType; |
| + if (compiler.trustTypeAnnotations |
| + && (element.isField() |
| + || element.isParameter())) { |
| + type = narrowType(dynamicType, element.computeType(compiler)); |
| + } else { |
| + type = dynamicType; |
| + } |
| } |
| assert(type != null); |
| return type; |
| @@ -1246,6 +1273,20 @@ |
| return union.containsAll(compiler) ? dynamicType : union; |
| } |
| } |
| + |
| + TypeMask narrowType(TypeMask type, DartType annotation) { |
| + if (annotation.isDynamic) return type; |
| + TypeMask otherType; |
| + if (annotation.kind == TypeKind.TYPEDEF |
| + || annotation.kind == TypeKind.FUNCTION) { |
| + otherType = functionType.nullable(); |
| + } else if (annotation.kind != TypeKind.INTERFACE) { |
| + return type; |
| + } else { |
| + otherType = new TypeMask.subtype(annotation); |
| + } |
| + return type.intersection(otherType, compiler); |
| + } |
| } |
| /** |
| @@ -2028,14 +2069,7 @@ |
| } else if (const SourceString("as") == op.source) { |
| TypeMask receiverType = visit(node.receiver); |
| DartType type = elements.getType(node.arguments.head); |
| - if (type.isDynamic) return receiverType; |
| - TypeMask asType = type.kind == TypeKind.TYPEDEF |
| - ? inferrer.functionType.nullable() |
| - : new TypeMask.subtype(type); |
| - // TODO(ngeoffray): Remove when inferrer.dynamicType is a proper |
| - // TypeMask. |
| - if (inferrer.isDynamicType(receiverType)) return asType; |
| - return receiverType.intersection(asType, compiler); |
| + return inferrer.narrowType(receiverType, type); |
| } else if (node.isParameterCheck) { |
| node.visitChildren(this); |
| return inferrer.boolType; |