From faac853b64804988b6b1a5809e659ad8e9fef55c Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Fri, 29 May 2015 17:03:05 -0700 Subject: [PATCH] Address PR feedback for generators --- src/compiler/checker.ts | 109 +++++++++++++++++++++------------------- src/compiler/parser.ts | 6 +-- src/compiler/types.ts | 2 +- 3 files changed, 60 insertions(+), 57 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 41762d4c446..76ec977491e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9725,42 +9725,43 @@ module ts { return elementType || anyType; } - - function getElementTypeOfIterable(iterable: Type, errorNode: Node): Type { - // We want to treat type as an iterable, and get the type it is an iterable of. The iterable - // must have the following structure (annotated with the names of the variables below): - // - // { // iterable - // [Symbol.iterator]: { // iteratorFunction - // (): Iterator - // } - // } - // - // T is the type we are after. At every level that involves analyzing return types - // of signatures, we union the return types of all the signatures. - // - // Another thing to note is that at any step of this process, we could run into a dead end, - // meaning either the property is missing, or we run into the anyType. If either of these things - // happens, we return undefined to signal that we could not find the iterated type. If a property - // is missing, and the previous step did not result in 'any', then we also give an error if the - // caller requested it. Then the caller can decide what to do in the case where there is no iterated - // type. This is different from returning anyType, because that would signify that we have matched the - // whole pattern and that T (above) is 'any'. - - if (allConstituentTypesHaveKind(iterable, TypeFlags.Any)) { + + /** + * We want to treat type as an iterable, and get the type it is an iterable of. The iterable + * must have the following structure (annotated with the names of the variables below): + * + * { // iterable + * [Symbol.iterator]: { // iteratorFunction + * (): Iterator + * } + * } + * + * T is the type we are after. At every level that involves analyzing return types + * of signatures, we union the return types of all the signatures. + * + * Another thing to note is that at any step of this process, we could run into a dead end, + * meaning either the property is missing, or we run into the anyType. If either of these things + * happens, we return undefined to signal that we could not find the iterated type. If a property + * is missing, and the previous step did not result in 'any', then we also give an error if the + * caller requested it. Then the caller can decide what to do in the case where there is no iterated + * type. This is different from returning anyType, because that would signify that we have matched the + * whole pattern and that T (above) is 'any'. + */ + function getElementTypeOfIterable(type: Type, errorNode: Node): Type { + if (type.flags & TypeFlags.Any) { return undefined; } - let typeAsIterable = iterable; + let typeAsIterable = type; if (!typeAsIterable.iterableElementType) { // As an optimization, if the type is instantiated directly using the globalIterableType (Iterable), // then just grab its type argument. - if ((iterable.flags & TypeFlags.Reference) && (iterable).target === globalIterableType) { - typeAsIterable.iterableElementType = (iterable).typeArguments[0]; + if ((type.flags & TypeFlags.Reference) && (type).target === globalIterableType) { + typeAsIterable.iterableElementType = (type).typeArguments[0]; } else { - let iteratorFunction = getTypeOfPropertyOfType(iterable, getPropertyNameForKnownSymbolName("iterator")); - if (iteratorFunction && allConstituentTypesHaveKind(iteratorFunction, TypeFlags.Any)) { + let iteratorFunction = getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("iterator")); + if (iteratorFunction && iteratorFunction.flags & TypeFlags.Any) { return undefined; } @@ -9779,32 +9780,34 @@ module ts { return typeAsIterable.iterableElementType; } - function getElementTypeOfIterator(iterator: Type, errorNode: Node): Type { - // This function has very similar logic as getElementTypeOfIterable, except that it operates on - // Iterators instead of Iterables. Here is the structure: - // - // { // iterator - // next: { // iteratorNextFunction - // (): { // iteratorNextResult - // value: T // iteratorNextValue - // } - // } - // } - // - if (allConstituentTypesHaveKind(iterator, TypeFlags.Any)) { + /** + * This function has very similar logic as getElementTypeOfIterable, except that it operates on + * Iterators instead of Iterables. Here is the structure: + * + * { // iterator + * next: { // iteratorNextFunction + * (): { // iteratorNextResult + * value: T // iteratorNextValue + * } + * } + * } + * + */ + function getElementTypeOfIterator(type: Type, errorNode: Node): Type { + if (type.flags & TypeFlags.Any) { return undefined; } - let typeAsIterator = iterator; + let typeAsIterator = type; if (!typeAsIterator.iteratorElementType) { // As an optimization, if the type is instantiated directly using the globalIteratorType (Iterator), // then just grab its type argument. - if ((iterator.flags & TypeFlags.Reference) && (iterator).target === globalIteratorType) { - typeAsIterator.iteratorElementType = (iterator).typeArguments[0]; + if ((type.flags & TypeFlags.Reference) && (type).target === globalIteratorType) { + typeAsIterator.iteratorElementType = (type).typeArguments[0]; } else { - let iteratorNextFunction = getTypeOfPropertyOfType(iterator, "next"); - if (iteratorNextFunction && allConstituentTypesHaveKind(iteratorNextFunction, TypeFlags.Any)) { + let iteratorNextFunction = getTypeOfPropertyOfType(type, "next"); + if (iteratorNextFunction && iteratorNextFunction.flags & TypeFlags.Any) { return undefined; } @@ -9817,7 +9820,7 @@ module ts { } let iteratorNextResult = getUnionType(map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iteratorNextResult, TypeFlags.Any)) { + if (iteratorNextResult.flags & TypeFlags.Any) { return undefined; } @@ -9836,19 +9839,19 @@ module ts { return typeAsIterator.iteratorElementType; } - function getElementTypeOfIterableIterator(iterableIterator: Type): Type { - if (allConstituentTypesHaveKind(iterableIterator, TypeFlags.Any)) { + function getElementTypeOfIterableIterator(type: Type): Type { + if (type.flags & TypeFlags.Any) { return undefined; } // As an optimization, if the type is instantiated directly using the globalIterableIteratorType (IterableIterator), // then just grab its type argument. - if ((iterableIterator.flags & TypeFlags.Reference) && (iterableIterator).target === globalIterableIteratorType) { - return (iterableIterator).typeArguments[0]; + if ((type.flags & TypeFlags.Reference) && (type).target === globalIterableIteratorType) { + return (type).typeArguments[0]; } - return getElementTypeOfIterable(iterableIterator, /*errorNode*/ undefined) || - getElementTypeOfIterator(iterableIterator, /*errorNode*/ undefined); + return getElementTypeOfIterable(type, /*errorNode*/ undefined) || + getElementTypeOfIterator(type, /*errorNode*/ undefined); } /** diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a4552e30ce5..f3f9f634dc4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4006,9 +4006,9 @@ module ts { property.questionToken = questionToken; property.type = parseTypeAnnotation(); - // For initializers, we always want to allow 'in' expressions. For instance properties specifically, - // since they are evaluated inside the constructor, we do *not* want to parse yield expressions, - // so we specifically turn the yield context off. The grammar would look something like this: + // For instance properties specifically, since they are evaluated inside the constructor, + // we do *not * want to parse yield expressions, so we specifically turn the yield context + // off. The grammar would look something like this: // // MemberVariableDeclaration[Yield]: // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In]; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d544717a2d8..941d69ed521 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1543,8 +1543,8 @@ module ts { numberIndexType: Type; // Numeric index type } - /* @internal */ // Just a place to cache element types of iterables and iterators + /* @internal */ export interface IterableOrIteratorType extends ObjectType, UnionType { iterableElementType?: Type; iteratorElementType?: Type;