@@ -2248,37 +2248,43 @@ abstract class TypeInformationVisitor<T> {
22482248 T visitYieldTypeInformation (YieldTypeInformation info);
22492249}
22502250
2251+ AbstractValue _intersection (AbstractValue type, AbstractValue otherType,
2252+ AbstractValueDomain abstractValueDomain, bool isNullable) {
2253+ if (isNullable) {
2254+ otherType = abstractValueDomain.includeNull (otherType);
2255+ }
2256+ return type == null
2257+ ? otherType
2258+ : abstractValueDomain.intersection (type, otherType);
2259+ }
2260+
22512261AbstractValue _narrowType (
22522262 JClosedWorld closedWorld, AbstractValue type, DartType annotation,
22532263 {bool isNullable: true }) {
22542264 annotation = annotation.withoutNullability;
22552265 AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
2256- AbstractValue otherType;
2257- if (closedWorld.dartTypes.isTopType (annotation)) {
2266+ // TODO(joshualitt): FutureOrType, TypeVariableType, and FunctionTypeVariable
2267+ // can be narrowed.
2268+ if (closedWorld.dartTypes.isTopType (annotation) ||
2269+ annotation is VoidType ||
2270+ annotation is NeverType ||
2271+ annotation is FutureOrType ||
2272+ annotation is TypeVariableType ||
2273+ annotation is FunctionTypeVariable ) {
22582274 return type;
22592275 } else if (annotation is InterfaceType ) {
22602276 if (annotation.element == closedWorld.commonElements.objectClass) {
22612277 return type;
22622278 }
2263- otherType = abstractValueDomain.createNonNullSubtype (annotation.element);
2264- } else if (annotation is VoidType ) {
2265- return type;
2279+ return _intersection (
2280+ type,
2281+ abstractValueDomain.createNonNullSubtype (annotation.element),
2282+ abstractValueDomain,
2283+ isNullable);
22662284 } else if (annotation is FunctionType ) {
2267- otherType = closedWorld.abstractValueDomain.functionType;
2268- } else if (annotation is FutureOrType ) {
2269- // TODO(johnniwinther): Narrow FutureOr types.
2270- return type;
2285+ return _intersection (type, closedWorld.abstractValueDomain.functionType,
2286+ abstractValueDomain, isNullable);
22712287 } else {
2272- assert (
2273- annotation is TypeVariableType || annotation is FunctionTypeVariable );
2274- // TODO(ngeoffray): Narrow to bound.
2275- return type;
2276- }
2277- if (isNullable) {
2278- otherType = abstractValueDomain.includeNull (otherType);
2279- }
2280- if (type == null ) {
2281- return otherType;
2288+ throw 'Unexpected annotation type $annotation ' ;
22822289 }
2283- return abstractValueDomain.intersection (type, otherType);
22842290}
0 commit comments