type checking for pseudoiterable

This commit is contained in:
Ron Buckton 2016-11-09 14:40:47 -08:00
parent 74ec093d01
commit bd867785bc
10 changed files with 240 additions and 176 deletions

View File

@ -10,6 +10,25 @@ namespace ts {
let nextMergeId = 1;
let nextFlowId = 1;
const enum EmitHelper {
Extends = 1 << 0,
Assign = 1 << 1,
Decorate = 1 << 2,
Metadata = 1 << 3,
Param = 1 << 4,
Awaiter = 1 << 5,
Generator = 1 << 6,
Values = 1 << 7,
Step = 1 << 8,
Close = 1 << 9,
Read = 1 << 10,
Spread = 1 << 11,
ForOfIncludes = Values | Step | Close,
SpreadIncludes = Read | Spread,
FirstEmitHelper = Extends,
LastEmitHelper = Spread
}
export function getNodeId(node: Node): number {
if (!node.id) {
node.id = nextNodeId;
@ -38,6 +57,8 @@ namespace ts {
// is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
// they no longer need the information (for example, if the user started editing again).
let cancellationToken: CancellationToken;
let requestedExternalHelpers: EmitHelper;
let externalHelpersModule: Symbol;
const Symbol = objectAllocator.getSymbolConstructor();
const Type = objectAllocator.getTypeConstructor();
@ -10430,7 +10451,7 @@ namespace ts {
const index = indexOf(arrayLiteral.elements, node);
return getTypeOfPropertyOfContextualType(type, "" + index)
|| getIndexTypeOfContextualType(type, IndexKind.Number)
|| getIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false);
|| getIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*checkAssignability*/ false);
}
return undefined;
}
@ -10649,6 +10670,10 @@ namespace ts {
// with this type. It is neither affected by it, nor does it propagate it to its operand.
// So the fact that contextualMapper is passed is not important, because the operand of a spread
// element is not contextually typed.
if (languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.SpreadIncludes);
}
const arrayOrIterableType = checkExpressionCached(node.expression, contextualMapper);
return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false);
}
@ -10679,7 +10704,7 @@ namespace ts {
// if there is no index type / iterated type.
const restArrayType = checkExpression((<SpreadElementExpression>e).expression, contextualMapper);
const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false);
getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*checkAssignability*/ false);
if (restElementType) {
elementTypes.push(restElementType);
}
@ -11024,6 +11049,10 @@ namespace ts {
function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
const type = checkExpression(node.expression);
const props = getPropertiesOfType(type);
if (compilerOptions.jsx === JsxEmit.React) {
checkEmitHelpers(node, EmitHelper.Assign);
}
for (const prop of props) {
// Is there a corresponding property in the element attributes type? Skip checking of properties
// that have already been assigned to, as these are not actually pushed into the resulting type
@ -13791,6 +13820,10 @@ namespace ts {
}
function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, contextualMapper?: TypeMapper): Type {
if (languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.Read);
}
// This elementType will be used if the specific property corresponding to this index is not
// present (aka the tuple element property). This call also checks that the parentType is in
// fact an iterable or array (depending on target language).
@ -14206,6 +14239,10 @@ namespace ts {
}
}
if (node.asteriskToken && languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.Values);
}
if (node.expression) {
const func = getContainingFunction(node);
// If the user's code is syntactically correct, the func should always have a star. After all,
@ -14666,6 +14703,17 @@ namespace ts {
checkGrammarFunctionLikeDeclaration(<FunctionLikeDeclaration>node);
}
if (isAsyncFunctionLike(node)) {
checkEmitHelpers(node, EmitHelper.Awaiter);
if (languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.Generator);
}
}
if (isSyntacticallyValidGenerator(node) && languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.Generator);
}
checkTypeParameters(node.typeParameters);
forEach(node.parameters, checkParameter);
@ -15792,7 +15840,15 @@ namespace ts {
error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning);
}
checkEmitHelpers(node, EmitHelper.Decorate);
if (node.kind === SyntaxKind.Parameter) {
checkEmitHelpers(node, EmitHelper.Param);
}
if (compilerOptions.emitDecoratorMetadata) {
checkEmitHelpers(node, EmitHelper.Metadata);
// we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
@ -16374,6 +16430,10 @@ namespace ts {
// For a binding pattern, check contained binding elements
if (isBindingPattern(node.name)) {
if (node.name.kind === SyntaxKind.ArrayBindingPattern && languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.Read);
}
forEach((<BindingPattern>node.name).elements, checkSourceElement);
}
// For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body
@ -16545,6 +16605,10 @@ namespace ts {
function checkForOfStatement(node: ForOfStatement): void {
checkGrammarForInOrForOfStatement(node);
if (node.kind === SyntaxKind.ForOfStatement && languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.ForOfIncludes);
}
// Check the LHS and RHS
// If the LHS is a declaration, just check it as a variable declaration, which will in turn check the RHS
// via checkRightHandSideOfForOf.
@ -16651,7 +16715,8 @@ namespace ts {
if (isTypeAny(inputType)) {
return inputType;
}
return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput) || unknownType;
return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, /*checkAssignability*/ true) || anyType;
}
/**
@ -16659,13 +16724,17 @@ namespace ts {
* we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
* of a pseudo-iterable or element type of an array like for ES2015 or earlier.
*/
function getIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean): Type {
function getIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean, checkAssignability: boolean): Type {
if (languageVersion >= ScriptTarget.ES2015) {
return getIteratedTypeOfIterable(inputType, errorNode);
const iteratedType = getIteratedTypeOfIterable(inputType, errorNode);
if (checkAssignability && errorNode && iteratedType) {
checkTypeAssignableTo(inputType, createIterableType(iteratedType), errorNode);
}
return iteratedType;
}
return allowStringInput
? getIteratedTypeOfPseudoIterableOrElementTypeOfArrayOrString(inputType, errorNode)
: getIteratedTypeOfPseudoIterableOrElementTypeOfArray(inputType, errorNode);
? getIteratedTypeOfPseudoIterableOrElementTypeOfArrayOrString(inputType, errorNode, checkAssignability)
: getIteratedTypeOfPseudoIterableOrElementTypeOfArray(inputType, errorNode, checkAssignability);
}
/**
@ -16821,12 +16890,15 @@ namespace ts {
* 1. Some constituent is neither a string nor an array.
* 2. Some constituent is a string and target is less than ES5 (because in ES3 string is not indexable).
*/
function getIteratedTypeOfPseudoIterableOrElementTypeOfArrayOrString(arrayOrStringType: Type, errorNode: Node): Type {
function getIteratedTypeOfPseudoIterableOrElementTypeOfArrayOrString(arrayOrStringType: Type, errorNode: Node, checkAssignability: boolean): Type {
Debug.assert(languageVersion < ScriptTarget.ES2015);
const elementType = getIteratedTypeOfIterable(arrayOrStringType, /*errorNode*/ undefined);
if (elementType) {
return elementType;
const iteratedType = getIteratedTypeOfIterable(arrayOrStringType, /*errorNode*/ undefined);
if (iteratedType) {
if (checkAssignability && errorNode) {
checkTypeAssignableTo(arrayOrStringType, createIterableType(iteratedType), errorNode);
}
return iteratedType;
}
// After we remove all types that are StringLike, we will know if there was a string constituent
@ -16863,8 +16935,8 @@ namespace ts {
// But if the input was just number, we want to say that number is not an array type
// or a string type.
const diagnostic = hasStringConstituent
? Diagnostics.Type_0_is_not_an_array_type
: Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
? Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_an_iterator_method_that_returns_an_iterator
: Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_an_iterator_method_that_returns_an_iterator;
error(errorNode, diagnostic, typeToString(arrayType));
}
}
@ -16884,18 +16956,21 @@ namespace ts {
return arrayElementType;
}
function getIteratedTypeOfPseudoIterableOrElementTypeOfArray(inputType: Type, errorNode: Node): Type {
function getIteratedTypeOfPseudoIterableOrElementTypeOfArray(inputType: Type, errorNode: Node, checkAssignability: boolean): Type {
Debug.assert(languageVersion < ScriptTarget.ES2015);
const elementType = getIteratedTypeOfIterable(inputType, /*errorNode*/ undefined);
if (elementType) {
return elementType;
const iteratedType = getIteratedTypeOfIterable(inputType, /*errorNode*/ undefined);
if (iteratedType) {
if (checkAssignability && errorNode) {
checkTypeAssignableTo(inputType, createIterableType(iteratedType), errorNode);
}
return iteratedType;
}
if (isArrayLikeType(inputType)) {
return getIndexTypeOfType(inputType, IndexKind.Number);
}
if (errorNode) {
error(errorNode, Diagnostics.Type_0_is_not_an_array_type, typeToString(inputType));
error(errorNode, Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_an_iterator_method_that_returns_an_iterator, typeToString(inputType));
}
return undefined;
}
@ -17281,6 +17356,10 @@ namespace ts {
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
if (baseTypeNode) {
if (languageVersion < ScriptTarget.ES2015) {
checkEmitHelpers(node, EmitHelper.Extends);
}
const baseTypes = getBaseTypes(type);
if (baseTypes.length && produceDiagnostics) {
const baseType = baseTypes[0];
@ -19714,8 +19793,6 @@ namespace ts {
// Initialize global symbol table
let augmentations: LiteralExpression[][];
let requestedExternalEmitHelpers: NodeFlags = 0;
let firstFileRequestingExternalHelpers: SourceFile;
for (const file of host.getSourceFiles()) {
if (!isExternalOrCommonJsModule(file)) {
mergeSymbolTable(globals, file.locals);
@ -19735,15 +19812,6 @@ namespace ts {
}
}
}
if ((compilerOptions.isolatedModules || isExternalModule(file)) && !file.isDeclarationFile) {
const fileRequestedExternalEmitHelpers = file.flags & NodeFlags.EmitHelperFlags;
if (fileRequestedExternalEmitHelpers) {
requestedExternalEmitHelpers |= fileRequestedExternalEmitHelpers;
if (firstFileRequestingExternalHelpers === undefined) {
firstFileRequestingExternalHelpers = file;
}
}
}
}
if (augmentations) {
@ -19808,53 +19876,55 @@ namespace ts {
const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
}
// If we have specified that we are importing helpers, we should report global
// errors if we cannot resolve the helpers external module, or if it does not have
// the necessary helpers exported.
if (compilerOptions.importHelpers && firstFileRequestingExternalHelpers) {
// Find the first reference to the helpers module.
const helpersModule = resolveExternalModule(
firstFileRequestingExternalHelpers,
externalHelpersModuleNameText,
Diagnostics.Cannot_find_module_0,
/*errorNode*/ undefined);
// If we found the module, report errors if it does not have the necessary exports.
if (helpersModule) {
const exports = helpersModule.exports;
if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) {
verifyHelperSymbol(exports, "__extends", SymbolFlags.Value);
}
if (requestedExternalEmitHelpers & NodeFlags.HasJsxSpreadAttributes && compilerOptions.jsx !== JsxEmit.Preserve) {
verifyHelperSymbol(exports, "__assign", SymbolFlags.Value);
}
if (requestedExternalEmitHelpers & NodeFlags.HasDecorators) {
verifyHelperSymbol(exports, "__decorate", SymbolFlags.Value);
if (compilerOptions.emitDecoratorMetadata) {
verifyHelperSymbol(exports, "__metadata", SymbolFlags.Value);
}
}
if (requestedExternalEmitHelpers & NodeFlags.HasParamDecorators) {
verifyHelperSymbol(exports, "__param", SymbolFlags.Value);
}
if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) {
verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value);
if (languageVersion < ScriptTarget.ES2015) {
verifyHelperSymbol(exports, "__generator", SymbolFlags.Value);
function checkEmitHelpers(node: Node, helpers: EmitHelper) {
if ((requestedExternalHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
const sourceFile = getSourceFileOfNode(node);
if (isEffectiveExternalModule(sourceFile, compilerOptions)) {
const helpersModule = resolveHelpersModule(sourceFile);
if (helpersModule !== unknownSymbol) {
const uncheckedHelpers = helpers & ~requestedExternalHelpers;
for (let helper = EmitHelper.FirstEmitHelper; helper <= EmitHelper.LastEmitHelper; helper <<= 1) {
if (uncheckedHelpers & helper) {
const name = getHelperName(helper);
const symbol = getSymbol(helpersModule.exports, escapeIdentifier(name), SymbolFlags.Value);
if (!symbol) {
diagnostics.add(createFileDiagnostic(sourceFile, 0, 0, Diagnostics.Module_0_has_no_exported_member_1, externalHelpersModuleNameText, name));
}
}
}
}
requestedExternalHelpers |= helpers;
}
}
}
function verifyHelperSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags) {
const symbol = getSymbol(symbols, escapeIdentifier(name), meaning);
if (!symbol) {
error(/*location*/ undefined, Diagnostics.Module_0_has_no_exported_member_1, externalHelpersModuleNameText, name);
function getHelperName(helper: EmitHelper) {
switch (helper) {
case EmitHelper.Extends: return "__extends";
case EmitHelper.Assign: return "__assign";
case EmitHelper.Decorate: return "__decorate";
case EmitHelper.Metadata: return "__metadata";
case EmitHelper.Param: return "__param";
case EmitHelper.Awaiter: return "__awaiter";
case EmitHelper.Generator: return "__generator";
case EmitHelper.Values: return "__values";
case EmitHelper.Step: return "__step";
case EmitHelper.Close: return "__close";
case EmitHelper.Read: return "__read";
case EmitHelper.Spread: return "__spread";
}
}
function resolveHelpersModule(node: SourceFile) {
if (!externalHelpersModule) {
externalHelpersModule = resolveExternalModule(node, externalHelpersModuleNameText, Diagnostics.Cannot_find_module_0, node) || unknownSymbol;
}
return externalHelpersModule;
}
function createInstantiatedPromiseLikeType(): ObjectType {
const promiseLikeType = getGlobalPromiseLikeType();
if (promiseLikeType !== emptyGenericType) {

View File

@ -417,6 +417,8 @@ namespace ts {
"webworker": "lib.webworker.d.ts",
"scripthost": "lib.scripthost.d.ts",
// ES2015 Or ESNext By-feature options
"iterator": "lib.iterator.d.ts",
"pseudoiterable": "lib.pseudoiterable.d.ts",
"es2015.core": "lib.es2015.core.d.ts",
"es2015.collection": "lib.es2015.collection.d.ts",
"es2015.generator": "lib.es2015.generator.d.ts",

View File

@ -1451,7 +1451,7 @@
"category": "Error",
"code": 2460
},
"Type '{0}' is not an array type.": {
"Type '{0}' is not an array type or does not have an '__iterator__()' method that returns an iterator.": {
"category": "Error",
"code": 2461
},
@ -1575,7 +1575,7 @@
"category": "Error",
"code": 2494
},
"Type '{0}' is not an array type or a string type.": {
"Type '{0}' is not an array type or a string type or does not have an '__iterator__()' method that returns an iterator.": {
"category": "Error",
"code": 2495
},

View File

@ -1749,7 +1749,7 @@ namespace ts {
text: `
var __close = (this && this.__close) || function (r) {
var m = !(r && r.done) && r.iterator["return"];
if (m) m.call(r.iterator);
if (m) return m.call(r.iterator);
};`
};
@ -1768,20 +1768,17 @@ namespace ts {
scoped: false,
text: `
var __read = (this && this.__read) || function (o, n) {
var m = o.__iterator__;
if (!m) return o;
var r = { iterator: m.call(o) }, ar = [], e;
try { while ((n === void 0 || n-- > 0) && __step(r)) ar.push(r.result.value); }
if (!(m = o.__iterator__)) return o;
var m, i = m.call(o), ar = [], r, e;
try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); }
catch (error) { e = { error: error }; }
finally { try { __close(r); } finally { if (e) throw e.error; } }
finally { try { if (m = !(r && r.done) && i["return"]) m.call(i); } finally { if (e) throw e.error; } }
return ar;
};`
};
export function createReadHelper(context: TransformationContext, iteratorRecord: Expression, count: number | undefined, location?: TextRange) {
context.requestEmitHelper(stepHelper);
context.requestEmitHelper(readHelper);
context.requestEmitHelper(closeHelper);
return createCall(
getHelperName("__read"),
/*typeArguments*/ undefined,
@ -1815,10 +1812,6 @@ namespace ts {
// Utilities
export function toFunctionBody(node: ConciseBody) {
return isBlock(node) ? node : createBlock([createReturn(node, /*location*/ node)], /*location*/ node);
}
export interface CallBinding {
target: LeftHandSideExpression;
thisArg: Expression;
@ -1858,6 +1851,10 @@ namespace ts {
thisArg = createThis();
target = languageVersion < ScriptTarget.ES2015 ? createIdentifier("_super", /*location*/ callee) : <PrimaryExpression>callee;
}
else if (getEmitFlags(callee) & EmitFlags.HelperName) {
thisArg = createVoidZero();
target = parenthesizeForAccess(callee);
}
else {
switch (callee.kind) {
case SyntaxKind.PropertyAccessExpression: {
@ -2164,8 +2161,6 @@ namespace ts {
return qualifiedName;
}
// Utilities
export function convertToFunctionBody(node: ConciseBody) {
return isBlock(node) ? node : createBlock([createReturn(node, /*location*/ node)], /*location*/ node);
}

View File

@ -247,16 +247,30 @@ namespace ts {
if (isEffectiveBindingPattern(bindingTarget)) {
const elements = getElementsOfEffectiveBindingPattern(bindingTarget);
const numElements = elements.length;
if (isEffectiveObjectBindingPattern(bindingTarget)) {
if (numElements !== 1) {
// For anything other than a single-element destructuring we need to generate a temporary
// to ensure value is evaluated exactly once. Additionally, if we have zero elements
// we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
// so in that case, we'll intentionally create that temporary.
const reuseIdentifierExpressions = !isDeclarationBindingElement(bindingElement) || numElements !== 0;
boundValue = ensureIdentifier(boundValue, reuseIdentifierExpressions, emitTempVariableAssignment, location);
}
if (isEffectiveArrayBindingPattern(bindingTarget) && !isArrayLiteralExpression(boundValue)) {
// Read the elements of the iterable into an array
boundValue = emitTempVariableAssignment(
createReadHelper(
context,
boundValue,
isEffectiveBindingElementWithRest(elements[numElements - 1])
? undefined
: numElements,
location
),
location
);
}
else if (numElements !== 1) {
// For anything other than a single-element destructuring we need to generate a temporary
// to ensure value is evaluated exactly once. Additionally, if we have zero elements
// we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
// so in that case, we'll intentionally create that temporary.
const reuseIdentifierExpressions = !isDeclarationBindingElement(bindingElement) || numElements !== 0;
boundValue = ensureIdentifier(boundValue, reuseIdentifierExpressions, emitTempVariableAssignment, location);
}
if (isEffectiveObjectBindingPattern(bindingTarget)) {
for (const element of elements) {
// Rewrite element to a declaration with an initializer that fetches property
flattenEffectiveBindingElement(
@ -275,21 +289,6 @@ namespace ts {
}
}
else {
if (!isArrayLiteralExpression(boundValue)) {
// Read the elements of the iterable into an array
boundValue = emitTempVariableAssignment(
createReadHelper(
context,
boundValue,
isEffectiveBindingElementWithRest(elements[numElements - 1])
? undefined
: numElements,
location
),
location
);
}
for (let i = 0; i < numElements; i++) {
const element = elements[i];
if (isOmittedExpression(element)) {

View File

@ -2079,7 +2079,8 @@ namespace ts {
// evaluated on every iteration.
const assignment = createAssignment(node.initializer, boundValue);
if (isDestructuringAssignment(assignment)) {
statements.push(visitNode(createStatement(assignment), visitor, isStatement));
aggregateTransformFlags(assignment);
statements.push(createStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
}
else {
assignment.end = node.initializer.end;

View File

@ -969,24 +969,29 @@ namespace ts {
// ar = _a.concat([%sent%, 2]);
const numInitialElements = countInitialNodesWithoutYield(elements);
const temp = declareLocal();
let hasAssignedTemp = false;
let temp: Identifier;
if (numInitialElements > 0) {
temp = declareLocal();
emitAssignment(temp,
createArrayLiteral(
visitNodes(elements, visitor, isExpression, 0, numInitialElements)
)
);
hasAssignedTemp = true;
}
const expressions = reduceLeft(elements, reduceElement, <Expression[]>[], numInitialElements);
return hasAssignedTemp
return temp
? createArrayConcat(temp, [createArrayLiteral(expressions)])
: createArrayLiteral(expressions);
function reduceElement(expressions: Expression[], element: Expression) {
if (containsYield(element) && expressions.length > 0) {
const hasAssignedTemp = temp !== undefined;
if (!temp) {
temp = declareLocal();
}
emitAssignment(
temp,
hasAssignedTemp
@ -996,7 +1001,6 @@ namespace ts {
)
: createArrayLiteral(expressions)
);
hasAssignedTemp = true;
expressions = [];
}
@ -1930,7 +1934,7 @@ namespace ts {
function cacheExpression(node: Expression): Identifier {
let temp: Identifier;
if (isGeneratedIdentifier(node)) {
if (isGeneratedIdentifier(node) || getEmitFlags(node) & EmitFlags.HelperName) {
return <Identifier>node;
}

View File

@ -3582,6 +3582,10 @@ namespace ts {
return node.symbol && getDeclarationOfKind(node.symbol, kind) === node;
}
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
return isExternalModule(node) || compilerOptions.isolatedModules;
}
// Node tests
//
// All node tests in the following list should *not* reference parent pointers so that

View File

@ -1,24 +1,13 @@
/// <reference path="lib.es2015.symbol.d.ts" />
interface SymbolConstructor {
/**
* A method that returns the default iterator for an object. Called by the semantics of the
/**
* A method that returns the default iterator for an object. Called by the semantics of the
* for-of statement.
*/
readonly iterator: symbol;
}
interface IteratorResult<T> {
done: boolean;
value: T;
}
interface Iterator<T> {
next(value?: any): IteratorResult<T>;
return?(value?: any): IteratorResult<T>;
throw?(e?: any): IteratorResult<T>;
}
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
@ -31,17 +20,17 @@ interface Array<T> {
/** Iterator */
[Symbol.iterator](): IterableIterator<T>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, T]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<T>;
@ -55,7 +44,7 @@ interface ArrayConstructor {
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from<T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): Array<U>;
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
@ -67,17 +56,17 @@ interface ReadonlyArray<T> {
/** Iterator */
[Symbol.iterator](): IterableIterator<T>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, T]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<T>;
@ -126,15 +115,15 @@ interface Promise<T> { }
interface PromiseConstructor {
/**
* Creates a Promise that is resolved with an array of results when all of the provided Promises
* Creates a Promise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any Promise is rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
all<TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
@ -152,20 +141,20 @@ interface String {
}
/**
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
interface Int8Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -184,20 +173,20 @@ interface Int8ArrayConstructor {
}
/**
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint8Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -216,22 +205,22 @@ interface Uint8ArrayConstructor {
}
/**
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
* If the requested number of bytes could not be allocated an exception is raised.
*/
interface Uint8ClampedArray {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -251,22 +240,22 @@ interface Uint8ClampedArrayConstructor {
}
/**
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Int16Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -285,20 +274,20 @@ interface Int16ArrayConstructor {
}
/**
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint16Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -317,20 +306,20 @@ interface Uint16ArrayConstructor {
}
/**
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Int32Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -349,20 +338,20 @@ interface Int32ArrayConstructor {
}
/**
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint32Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -386,15 +375,15 @@ interface Uint32ArrayConstructor {
*/
interface Float32Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
@ -413,20 +402,20 @@ interface Float32ArrayConstructor {
}
/**
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
interface Float64Array {
[Symbol.iterator](): IterableIterator<number>;
/**
/**
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
/**
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
/**
* Returns an list of values in the array
*/
values(): IterableIterator<number>;

10
src/lib/es5.d.ts vendored
View File

@ -1338,11 +1338,6 @@ interface PromiseLike<T> {
onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
}
interface ArrayLike<T> {
readonly length: number;
readonly [n: number]: T;
}
interface IteratorResult<T> {
done: boolean;
value: T;
@ -1362,6 +1357,11 @@ interface PseudoIterableIterator<T> extends Iterator<T> {
__iterator__(): PseudoIterableIterator<T>;
}
interface ArrayLike<T> {
readonly length: number;
readonly [n: number]: T;
}
/**
* Represents a raw buffer of binary data, which is used to store data for the
* different typed arrays. ArrayBuffers cannot be read from or written to directly,