Fix getIteratedType to work with 'any' at all levels

This commit is contained in:
Jason Freeman
2015-02-24 13:35:42 -08:00
parent 057108646d
commit 732637dd54
16 changed files with 235 additions and 1 deletions

View File

@@ -8846,7 +8846,7 @@ module ts {
function getIteratedType(iterable: Type, expressionForError: Expression): Type {
Debug.assert(languageVersion >= ScriptTarget.ES6);
if (allConstituentTypesHaveKind(iterable, TypeFlags.Any)) {
return anyType;
return iterable; // any or unknown
}
// We want to treat type as an iterable, and get the type it is an iterable of. The iterable
@@ -8867,6 +8867,10 @@ module ts {
// 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.
var iteratorFunction = getTypeOfPropertyOfType(iterable, getPropertyNameForKnownSymbolName("iterator"));
if (iteratorFunction && allConstituentTypesHaveKind(iteratorFunction, TypeFlags.Any)) {
return iteratorFunction; // any or unknown
}
var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, SignatureKind.Call) : emptyArray;
if (iteratorFunctionSignatures.length === 0) {
error(expressionForError, Diagnostics.The_right_hand_side_of_a_for_of_statement_must_have_a_Symbol_iterator_method_that_returns_an_iterator);
@@ -8874,8 +8878,15 @@ module ts {
}
var iterator = getUnionType(map(iteratorFunctionSignatures, getReturnTypeOfSignature));
if (allConstituentTypesHaveKind(iterator, TypeFlags.Any)) {
return iterator; // any or unknown
}
var iteratorNextFunction = getTypeOfPropertyOfType(iterator, "next");
if (iteratorNextFunction && allConstituentTypesHaveKind(iteratorNextFunction, TypeFlags.Any)) {
return iteratorNextFunction; // any or unknown
}
var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, SignatureKind.Call) : emptyArray;
if (iteratorNextFunctionSignatures.length === 0) {
error(expressionForError, Diagnostics.The_iterator_returned_by_the_right_hand_side_of_a_for_of_statement_must_have_a_next_method);
@@ -8883,6 +8894,9 @@ module ts {
}
var iteratorNextResult = getUnionType(map(iteratorNextFunctionSignatures, getReturnTypeOfSignature));
if (allConstituentTypesHaveKind(iteratorNextResult, TypeFlags.Any)) {
return iteratorNextResult; // any or unknown
}
var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value");
if (!iteratorNextValue) {

View File

@@ -0,0 +1,8 @@
//// [for-of24.ts]
var x: any;
for (var v of x) { }
//// [for-of24.js]
var x;
for (var v of x) { }

View File

@@ -0,0 +1,8 @@
=== tests/cases/conformance/es6/for-ofStatements/for-of24.ts ===
var x: any;
>x : any
for (var v of x) { }
>v : any
>x : any

View File

@@ -0,0 +1,21 @@
//// [for-of25.ts]
var x: any;
for (var v of new StringIterator) { }
class StringIterator {
[Symbol.iterator]() {
return x;
}
}
//// [for-of25.js]
var x;
for (var v of new StringIterator) { }
var StringIterator = (function () {
function StringIterator() {
}
StringIterator.prototype[Symbol.iterator] = function () {
return x;
};
return StringIterator;
})();

View File

@@ -0,0 +1,21 @@
=== tests/cases/conformance/es6/for-ofStatements/for-of25.ts ===
var x: any;
>x : any
for (var v of new StringIterator) { }
>v : any
>new StringIterator : StringIterator
>StringIterator : typeof StringIterator
class StringIterator {
>StringIterator : StringIterator
[Symbol.iterator]() {
>Symbol.iterator : symbol
>Symbol : SymbolConstructor
>iterator : symbol
return x;
>x : any
}
}

View File

@@ -0,0 +1,27 @@
//// [for-of26.ts]
var x: any;
for (var v of new StringIterator) { }
class StringIterator {
next() {
return x;
}
[Symbol.iterator]() {
return this;
}
}
//// [for-of26.js]
var x;
for (var v of new StringIterator) { }
var StringIterator = (function () {
function StringIterator() {
}
StringIterator.prototype.next = function () {
return x;
};
StringIterator.prototype[Symbol.iterator] = function () {
return this;
};
return StringIterator;
})();

View File

@@ -0,0 +1,27 @@
=== tests/cases/conformance/es6/for-ofStatements/for-of26.ts ===
var x: any;
>x : any
for (var v of new StringIterator) { }
>v : any
>new StringIterator : StringIterator
>StringIterator : typeof StringIterator
class StringIterator {
>StringIterator : StringIterator
next() {
>next : () => any
return x;
>x : any
}
[Symbol.iterator]() {
>Symbol.iterator : symbol
>Symbol : SymbolConstructor
>iterator : symbol
return this;
>this : StringIterator
}
}

View File

@@ -0,0 +1,14 @@
//// [for-of27.ts]
for (var v of new StringIterator) { }
class StringIterator {
[Symbol.iterator]: any;
}
//// [for-of27.js]
for (var v of new StringIterator) { }
var StringIterator = (function () {
function StringIterator() {
}
return StringIterator;
})();

View File

@@ -0,0 +1,14 @@
=== tests/cases/conformance/es6/for-ofStatements/for-of27.ts ===
for (var v of new StringIterator) { }
>v : any
>new StringIterator : StringIterator
>StringIterator : typeof StringIterator
class StringIterator {
>StringIterator : StringIterator
[Symbol.iterator]: any;
>Symbol.iterator : symbol
>Symbol : SymbolConstructor
>iterator : symbol
}

View File

@@ -0,0 +1,20 @@
//// [for-of28.ts]
for (var v of new StringIterator) { }
class StringIterator {
next: any;
[Symbol.iterator]() {
return this;
}
}
//// [for-of28.js]
for (var v of new StringIterator) { }
var StringIterator = (function () {
function StringIterator() {
}
StringIterator.prototype[Symbol.iterator] = function () {
return this;
};
return StringIterator;
})();

View File

@@ -0,0 +1,21 @@
=== tests/cases/conformance/es6/for-ofStatements/for-of28.ts ===
for (var v of new StringIterator) { }
>v : any
>new StringIterator : StringIterator
>StringIterator : typeof StringIterator
class StringIterator {
>StringIterator : StringIterator
next: any;
>next : any
[Symbol.iterator]() {
>Symbol.iterator : symbol
>Symbol : SymbolConstructor
>iterator : symbol
return this;
>this : StringIterator
}
}

View File

@@ -0,0 +1,3 @@
//@target: ES6
var x: any;
for (var v of x) { }

View File

@@ -0,0 +1,9 @@
//@target: ES6
var x: any;
for (var v of new StringIterator) { }
class StringIterator {
[Symbol.iterator]() {
return x;
}
}

View File

@@ -0,0 +1,12 @@
//@target: ES6
var x: any;
for (var v of new StringIterator) { }
class StringIterator {
next() {
return x;
}
[Symbol.iterator]() {
return this;
}
}

View File

@@ -0,0 +1,6 @@
//@target: ES6
for (var v of new StringIterator) { }
class StringIterator {
[Symbol.iterator]: any;
}

View File

@@ -0,0 +1,9 @@
//@target: ES6
for (var v of new StringIterator) { }
class StringIterator {
next: any;
[Symbol.iterator]() {
return this;
}
}