Merge branch 'master' into baseZero

Conflicts:
	src/harness/harnessLanguageService.ts
This commit is contained in:
Cyrus Najmabadi
2015-02-20 16:56:58 -08:00
651 changed files with 13884 additions and 1545 deletions
+8 -13
View File
@@ -51,17 +51,6 @@ module ts {
}
}
/**
* A declaration has a dynamic name if both of the following are true:
* 1. The declaration has a computed property name
* 2. The computed name is *not* expressed as Symbol.<name>, where name
* is a property of the Symbol constructor that denotes a built in
* Symbol.
*/
export function hasDynamicName(declaration: Declaration): boolean {
return declaration.name && declaration.name.kind === SyntaxKind.ComputedPropertyName;
}
export function bindSourceFile(file: SourceFile): void {
var start = new Date().getTime();
bindSourceFileWorker(file);
@@ -98,13 +87,18 @@ module ts {
if (symbolKind & SymbolFlags.Value && !symbol.valueDeclaration) symbol.valueDeclaration = node;
}
// Should not be called on a declaration with a computed property name.
// Should not be called on a declaration with a computed property name,
// unless it is a well known Symbol.
function getDeclarationName(node: Declaration): string {
if (node.name) {
if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) {
return '"' + (<LiteralExpression>node.name).text + '"';
}
Debug.assert(!hasDynamicName(node));
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
var nameExpression = (<ComputedPropertyName>node.name).expression;
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
return getPropertyNameForKnownSymbolName((<PropertyAccessExpression>nameExpression).name.text);
}
return (<Identifier | LiteralExpression>node.name).text;
}
switch (node.kind) {
@@ -495,6 +489,7 @@ module ts {
case SyntaxKind.CatchClause:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.SwitchStatement:
bindChildren(node, 0, /*isBlockScopeContainer*/ true);
break;
+315 -97
View File
@@ -67,6 +67,7 @@ module ts {
var stringType = createIntrinsicType(TypeFlags.String, "string");
var numberType = createIntrinsicType(TypeFlags.Number, "number");
var booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean");
var esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
var voidType = createIntrinsicType(TypeFlags.Void, "void");
var undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined");
var nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefinedOrNull, "null");
@@ -84,6 +85,7 @@ module ts {
var globals: SymbolTable = {};
var globalArraySymbol: Symbol;
var globalESSymbolConstructorSymbol: Symbol;
var globalObjectType: ObjectType;
var globalFunctionType: ObjectType;
@@ -93,6 +95,7 @@ module ts {
var globalBooleanType: ObjectType;
var globalRegExpType: ObjectType;
var globalTemplateStringsArrayType: ObjectType;
var globalESSymbolType: ObjectType;
var anyArrayType: Type;
@@ -120,6 +123,10 @@ module ts {
"boolean": {
type: booleanType,
flags: TypeFlags.Boolean
},
"symbol": {
type: esSymbolType,
flags: TypeFlags.ESSymbol
}
};
@@ -706,9 +713,15 @@ module ts {
return type;
}
// A reserved member name starts with two underscores followed by a non-underscore
// A reserved member name starts with two underscores, but the third character cannot be an underscore
// or the @ symbol. A third underscore indicates an escaped form of an identifer that started
// with at least two underscores. The @ character indicates that the name is denoted by a well known ES
// Symbol instance.
function isReservedMemberName(name: string) {
return name.charCodeAt(0) === CharacterCodes._ && name.charCodeAt(1) === CharacterCodes._ && name.charCodeAt(2) !== CharacterCodes._;
return name.charCodeAt(0) === CharacterCodes._ &&
name.charCodeAt(1) === CharacterCodes._ &&
name.charCodeAt(2) !== CharacterCodes._ &&
name.charCodeAt(2) !== CharacterCodes.at;
}
function getNamedMembers(members: SymbolTable): Symbol[] {
@@ -2489,9 +2502,9 @@ module ts {
return getPropertiesOfObjectType(getApparentType(type));
}
// For a type parameter, return the base constraint of the type parameter. For the string, number, and
// boolean primitive types, return the corresponding object types.Otherwise return the type itself.
// Note that the apparent type of a union type is the union type itself.
// For a type parameter, return the base constraint of the type parameter. For the string, number,
// boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
// type itself. Note that the apparent type of a union type is the union type itself.
function getApparentType(type: Type): Type {
if (type.flags & TypeFlags.TypeParameter) {
do {
@@ -2510,6 +2523,9 @@ module ts {
else if (type.flags & TypeFlags.Boolean) {
type = globalBooleanType;
}
else if (type.flags & TypeFlags.ESSymbol) {
type = globalESSymbolType;
}
return type;
}
@@ -2999,12 +3015,24 @@ module ts {
return <ObjectType>type;
}
function getGlobalSymbol(name: string): Symbol {
return resolveName(undefined, name, SymbolFlags.Type, Diagnostics.Cannot_find_global_type_0, name);
function getGlobalValueSymbol(name: string): Symbol {
return getGlobalSymbol(name, SymbolFlags.Value, Diagnostics.Cannot_find_global_value_0);
}
function getGlobalTypeSymbol(name: string): Symbol {
return getGlobalSymbol(name, SymbolFlags.Type, Diagnostics.Cannot_find_global_type_0);
}
function getGlobalSymbol(name: string, meaning: SymbolFlags, diagnostic: DiagnosticMessage): Symbol {
return resolveName(undefined, name, meaning, diagnostic, name);
}
function getGlobalType(name: string): ObjectType {
return getTypeOfGlobalSymbol(getGlobalSymbol(name), 0);
return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), 0);
}
function getGlobalESSymbolConstructorSymbol() {
return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol"));
}
function createArrayType(elementType: Type): Type {
@@ -3174,6 +3202,8 @@ module ts {
return numberType;
case SyntaxKind.BooleanKeyword:
return booleanType;
case SyntaxKind.SymbolKeyword:
return esSymbolType;
case SyntaxKind.VoidKeyword:
return voidType;
case SyntaxKind.StringLiteral:
@@ -4612,6 +4642,7 @@ module ts {
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.ReturnStatement:
case SyntaxKind.WithStatement:
case SyntaxKind.SwitchStatement:
@@ -4740,7 +4771,7 @@ module ts {
if (assumeTrue) {
// Assumed result is true. If check was not for a primitive type, remove all primitive types
if (!typeInfo) {
return removeTypesFromUnionType(type, /*typeKind*/ TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.Boolean, /*isOfTypeKind*/ true);
return removeTypesFromUnionType(type, /*typeKind*/ TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.Boolean | TypeFlags.ESSymbol, /*isOfTypeKind*/ true);
}
// Check was for a primitive type, return that primitive type if it is a subtype
if (isTypeSubtypeOf(typeInfo.type, type)) {
@@ -5475,7 +5506,7 @@ module ts {
function isNumericComputedName(name: ComputedPropertyName): boolean {
// It seems odd to consider an expression of type Any to result in a numeric name,
// but this behavior is consistent with checkIndexedAccess
return isTypeOfKind(checkComputedPropertyName(name), TypeFlags.Any | TypeFlags.NumberLike);
return allConstituentTypesHaveKind(checkComputedPropertyName(name), TypeFlags.Any | TypeFlags.NumberLike);
}
function isNumericLiteralName(name: string) {
@@ -5508,10 +5539,13 @@ module ts {
if (!links.resolvedType) {
links.resolvedType = checkExpression(node.expression);
// This will allow types number, string, or any. It will also allow enums, the unknown
// This will allow types number, string, symbol or any. It will also allow enums, the unknown
// type, and any union of these types (like string | number).
if (!isTypeOfKind(links.resolvedType, TypeFlags.Any | TypeFlags.NumberLike | TypeFlags.StringLike)) {
error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_or_any);
if (!allConstituentTypesHaveKind(links.resolvedType, TypeFlags.Any | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) {
error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
}
else {
checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true);
}
}
@@ -5760,8 +5794,8 @@ module ts {
// See if we can index as a property.
if (node.argumentExpression) {
if (node.argumentExpression.kind === SyntaxKind.StringLiteral || node.argumentExpression.kind === SyntaxKind.NumericLiteral) {
var name = (<LiteralExpression>node.argumentExpression).text;
var name = getPropertyNameForIndexedAccess(node.argumentExpression, indexType);
if (name !== undefined) {
var prop = getPropertyOfType(objectType, name);
if (prop) {
getNodeLinks(node).resolvedSymbol = prop;
@@ -5775,10 +5809,10 @@ module ts {
}
// Check for compatible indexer types.
if (isTypeOfKind(indexType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) {
if (allConstituentTypesHaveKind(indexType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
// Try to use a number indexer.
if (isTypeOfKind(indexType, TypeFlags.Any | TypeFlags.NumberLike)) {
if (allConstituentTypesHaveKind(indexType, TypeFlags.Any | TypeFlags.NumberLike)) {
var numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number);
if (numberIndexType) {
return numberIndexType;
@@ -5800,11 +5834,78 @@ module ts {
}
// REVIEW: Users should know the type that was actually used.
error(node, Diagnostics.An_index_expression_argument_must_be_of_type_string_number_or_any);
error(node, Diagnostics.An_index_expression_argument_must_be_of_type_string_number_symbol_or_any);
return unknownType;
}
/**
* If indexArgumentExpression is a string literal or number literal, returns its text.
* If indexArgumentExpression is a well known symbol, returns the property name corresponding
* to this symbol, as long as it is a proper symbol reference.
* Otherwise, returns undefined.
*/
function getPropertyNameForIndexedAccess(indexArgumentExpression: Expression, indexArgumentType: Type): string {
if (indexArgumentExpression.kind === SyntaxKind.StringLiteral || indexArgumentExpression.kind === SyntaxKind.NumericLiteral) {
return (<LiteralExpression>indexArgumentExpression).text;
}
if (checkThatExpressionIsProperSymbolReference(indexArgumentExpression, indexArgumentType, /*reportError*/ false)) {
var rightHandSideName = (<Identifier>(<PropertyAccessExpression>indexArgumentExpression).name).text;
return getPropertyNameForKnownSymbolName(rightHandSideName);
}
return undefined;
}
/**
* A proper symbol reference requires the following:
* 1. The property access denotes a property that exists
* 2. The expression is of the form Symbol.<identifier>
* 3. The property access is of the primitive type symbol.
* 4. Symbol in this context resolves to the global Symbol object
*/
function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
if (expressionType === unknownType) {
// There is already an error, so no need to report one.
return false;
}
if (!isWellKnownSymbolSyntactically(expression)) {
return false;
}
// Make sure the property type is the primitive symbol type
if ((expressionType.flags & TypeFlags.ESSymbol) === 0) {
if (reportError) {
error(expression, Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, getTextOfNode(expression));
}
return false;
}
// The name is Symbol.<someName>, so make sure Symbol actually resolves to the
// global Symbol object
var leftHandSide = <Identifier>(<PropertyAccessExpression>expression).expression;
var leftHandSideSymbol = getResolvedSymbol(leftHandSide);
if (!leftHandSideSymbol) {
return false;
}
var globalESSymbol = getGlobalESSymbolConstructorSymbol();
if (!globalESSymbol) {
// Already errored when we tried to look up the symbol
return false;
}
if (leftHandSideSymbol !== globalESSymbol) {
if (reportError) {
error(leftHandSide, Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object);
}
return false;
}
return true;
}
function resolveUntypedCall(node: CallLikeExpression): Signature {
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
checkExpression((<TaggedTemplateExpression>node).template);
@@ -6719,7 +6820,7 @@ module ts {
}
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
if (!isTypeOfKind(type, TypeFlags.Any | TypeFlags.NumberLike)) {
if (!allConstituentTypesHaveKind(type, TypeFlags.Any | TypeFlags.NumberLike)) {
error(operand, diagnostic);
return false;
}
@@ -6835,6 +6936,9 @@ module ts {
case SyntaxKind.PlusToken:
case SyntaxKind.MinusToken:
case SyntaxKind.TildeToken:
if (someConstituentTypeHasKind(operandType, TypeFlags.ESSymbol)) {
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
}
return numberType;
case SyntaxKind.ExclamationToken:
return booleanType;
@@ -6870,8 +6974,26 @@ module ts {
return numberType;
}
// Return true if type has the given flags, or is a union type composed of types that all have those flags
function isTypeOfKind(type: Type, kind: TypeFlags): boolean {
// Just like isTypeOfKind below, except that it returns true if *any* constituent
// has this kind.
function someConstituentTypeHasKind(type: Type, kind: TypeFlags): boolean {
if (type.flags & kind) {
return true;
}
if (type.flags & TypeFlags.Union) {
var types = (<UnionType>type).types;
for (var i = 0; i < types.length; i++) {
if (types[i].flags & kind) {
return true;
}
}
return false;
}
return false;
}
// Return true if type has the given flags, or is a union type composed of types that all have those flags.
function allConstituentTypesHaveKind(type: Type, kind: TypeFlags): boolean {
if (type.flags & kind) {
return true;
}
@@ -6901,7 +7023,7 @@ module ts {
// and the right operand to be of type Any or a subtype of the 'Function' interface type.
// The result is always of the Boolean primitive type.
// NOTE: do not raise error if leftType is unknown as related error was already reported
if (isTypeOfKind(leftType, TypeFlags.Primitive)) {
if (allConstituentTypesHaveKind(leftType, TypeFlags.Primitive)) {
error(node.left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
// NOTE: do not raise error if right is unknown as related error was already reported
@@ -6916,10 +7038,10 @@ module ts {
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
// and the right operand to be of type Any, an object type, or a type parameter type.
// The result is always of the Boolean primitive type.
if (!isTypeOfKind(leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) {
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number);
if (!allConstituentTypesHaveKind(leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
if (!isTypeOfKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
if (!allConstituentTypesHaveKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
return booleanType;
@@ -7080,19 +7202,26 @@ module ts {
if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType;
var resultType: Type;
if (isTypeOfKind(leftType, TypeFlags.NumberLike) && isTypeOfKind(rightType, TypeFlags.NumberLike)) {
if (allConstituentTypesHaveKind(leftType, TypeFlags.NumberLike) && allConstituentTypesHaveKind(rightType, TypeFlags.NumberLike)) {
// Operands of an enum type are treated as having the primitive type Number.
// If both operands are of the Number primitive type, the result is of the Number primitive type.
resultType = numberType;
}
else if (isTypeOfKind(leftType, TypeFlags.StringLike) || isTypeOfKind(rightType, TypeFlags.StringLike)) {
// If one or both operands are of the String primitive type, the result is of the String primitive type.
resultType = stringType;
}
else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) {
// Otherwise, the result is of type Any.
// NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
resultType = anyType;
else {
if (allConstituentTypesHaveKind(leftType, TypeFlags.StringLike) || allConstituentTypesHaveKind(rightType, TypeFlags.StringLike)) {
// If one or both operands are of the String primitive type, the result is of the String primitive type.
resultType = stringType;
}
else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) {
// Otherwise, the result is of type Any.
// NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
resultType = anyType;
}
// Symbols are not allowed at all in arithmetic expressions
if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
return resultType;
}
}
if (!resultType) {
@@ -7104,14 +7233,18 @@ module ts {
checkAssignmentOperator(resultType);
}
return resultType;
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
case SyntaxKind.ExclamationEqualsEqualsToken:
case SyntaxKind.LessThanToken:
case SyntaxKind.GreaterThanToken:
case SyntaxKind.LessThanEqualsToken:
case SyntaxKind.GreaterThanEqualsToken:
if (!checkForDisallowedESSymbolOperand(operator)) {
return booleanType;
}
// Fall through
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
case SyntaxKind.ExclamationEqualsEqualsToken:
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
reportOperatorError();
}
@@ -7131,6 +7264,20 @@ module ts {
return rightType;
}
// Return type is true if there was no error, false if there was an error.
function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
var offendingSymbolOperand =
someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? node.left :
someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? node.right :
undefined;
if (offendingSymbolOperand) {
error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(operator));
return false;
}
return true;
}
function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind {
switch (operator) {
case SyntaxKind.BarToken:
@@ -7216,7 +7363,10 @@ module ts {
}
function checkPropertyAssignment(node: PropertyAssignment, contextualMapper?: TypeMapper): Type {
if (hasDynamicName(node)) {
// Do not use hasDynamicName here, because that returns false for well known symbols.
// We want to perform checkComputedPropertyName for all computed properties, including
// well known symbols.
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
checkComputedPropertyName(<ComputedPropertyName>node.name);
}
@@ -7227,7 +7377,10 @@ module ts {
// Grammar checking
checkGrammarMethod(node);
if (hasDynamicName(node)) {
// Do not use hasDynamicName here, because that returns false for well known symbols.
// We want to perform checkComputedPropertyName for all computed properties, including
// well known symbols.
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
checkComputedPropertyName(<ComputedPropertyName>node.name);
}
@@ -7490,7 +7643,7 @@ module ts {
function checkPropertyDeclaration(node: PropertyDeclaration) {
// Grammar checking
checkGrammarModifiers(node) || checkGrammarProperty(node);
checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
checkVariableLikeDeclaration(node);
}
@@ -8039,12 +8192,16 @@ module ts {
function checkFunctionLikeDeclaration(node: FunctionLikeDeclaration): void {
checkSignatureDeclaration(node);
if (hasDynamicName(node)) {
// Do not use hasDynamicName here, because that returns false for well known symbols.
// We want to perform checkComputedPropertyName for all computed properties, including
// well known symbols.
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
// This check will account for methods in class/interface declarations,
// as well as accessors in classes/object literals
checkComputedPropertyName(<ComputedPropertyName>node.name);
}
else {
if (!hasDynamicName(node)) {
// first we want to check the local symbol that contain this declaration
// - if node.localSymbol !== undefined - this is current declaration is exported and localSymbol points to the local symbol
// - if node.localSymbol === undefined - this node is non-exported so we can just pick the result of getSymbolOfNode
@@ -8081,7 +8238,7 @@ module ts {
function checkBlock(node: Block) {
// Grammar checking for SyntaxKind.Block
if (node.kind === SyntaxKind.Block) {
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
}
forEach(node.statements, checkSourceElement);
@@ -8302,12 +8459,14 @@ module ts {
function checkVariableLikeDeclaration(node: VariableLikeDeclaration) {
checkSourceElement(node.type);
// For a computed property, just check the initializer and exit
if (hasDynamicName(node)) {
// Do not use hasDynamicName here, because that returns false for well known symbols.
// We want to perform checkComputedPropertyName for all computed properties, including
// well known symbols.
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
checkComputedPropertyName(<ComputedPropertyName>node.name);
if (node.initializer) {
checkExpressionCached(node.initializer);
}
return;
}
// For a binding pattern, check contained binding elements
if (isBindingPattern(node.name)) {
@@ -8395,14 +8554,14 @@ module ts {
function checkExpressionStatement(node: ExpressionStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node)
checkGrammarStatementInAmbientContext(node)
checkExpression(node.expression);
}
function checkIfStatement(node: IfStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
checkExpression(node.expression);
checkSourceElement(node.thenStatement);
@@ -8411,7 +8570,7 @@ module ts {
function checkDoStatement(node: DoStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
checkSourceElement(node.statement);
checkExpression(node.expression);
@@ -8419,7 +8578,7 @@ module ts {
function checkWhileStatement(node: WhileStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
checkExpression(node.expression);
checkSourceElement(node.statement);
@@ -8427,7 +8586,7 @@ module ts {
function checkForStatement(node: ForStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.initializer && node.initializer.kind == SyntaxKind.VariableDeclarationList) {
checkGrammarVariableDeclarationList(<VariableDeclarationList>node.initializer);
}
@@ -8447,18 +8606,14 @@ module ts {
checkSourceElement(node.statement);
}
function checkForOfStatement(node: ForOfStatement) {
// TODO: not yet implemented
checkGrammarForOfStatement(node);
}
function checkForInStatement(node: ForInStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (node.initializer.kind === SyntaxKind.VariableDeclarationList) {
var variableList = <VariableDeclarationList>node.initializer;
if (!checkGrammarVariableDeclarationList(variableList)) {
if (variableList.declarations.length > 1) {
grammarErrorOnFirstToken(variableList.declarations[1], Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement);
}
}
}
}
checkGrammarForInOrForOfStatement(node);
// TypeScript 1.0 spec (April 2014): 5.4
// In a 'for-in' statement of the form
@@ -8470,9 +8625,6 @@ module ts {
if (variableDeclarationList.declarations.length >= 1) {
var decl = variableDeclarationList.declarations[0];
checkVariableDeclaration(decl);
if (decl.type) {
error(decl, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation);
}
}
}
else {
@@ -8482,7 +8634,7 @@ module ts {
// and Expr must be an expression of type Any, an object type, or a type parameter type.
var varExpr = <Expression>node.initializer;
var exprType = checkExpression(varExpr);
if (exprType !== anyType && exprType !== stringType) {
if (!allConstituentTypesHaveKind(exprType, TypeFlags.Any | TypeFlags.StringLike)) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
}
else {
@@ -8494,7 +8646,7 @@ module ts {
var exprType = checkExpression(node.expression);
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
// in this case error about missing name is already reported - do not report extra one
if (!isTypeOfKind(exprType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
if (!allConstituentTypesHaveKind(exprType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
@@ -8503,7 +8655,7 @@ module ts {
function checkBreakOrContinueStatement(node: BreakOrContinueStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
// TODO: Check that target label is valid
}
@@ -8514,7 +8666,7 @@ module ts {
function checkReturnStatement(node: ReturnStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
var functionBlock = getContainingFunction(node);
if (!functionBlock) {
grammarErrorOnFirstToken(node, Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
@@ -8545,7 +8697,7 @@ module ts {
function checkWithStatement(node: WithStatement) {
// Grammar checking for withStatement
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.parserContextFlags & ParserContextFlags.StrictMode) {
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
}
@@ -8557,7 +8709,7 @@ module ts {
function checkSwitchStatement(node: SwitchStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
var firstDefaultClause: CaseOrDefaultClause;
var hasDuplicateDefaultClause = false;
@@ -8594,7 +8746,7 @@ module ts {
function checkLabeledStatement(node: LabeledStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
var current = node.parent;
while (current) {
if (isAnyFunction(current)) {
@@ -8615,7 +8767,7 @@ module ts {
function checkThrowStatement(node: ThrowStatement) {
// Grammar checking
if (!checkGrammarForStatementInAmbientContext(node)) {
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.expression === undefined) {
grammarErrorAfterFirstToken(node, Diagnostics.Line_break_not_permitted_here);
}
@@ -8628,7 +8780,7 @@ module ts {
function checkTryStatement(node: TryStatement) {
// Grammar checking
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
checkBlock(node.tryBlock);
var catchClause = node.catchClause;
@@ -8745,6 +8897,7 @@ module ts {
case "number":
case "boolean":
case "string":
case "symbol":
case "void":
error(name, message, (<Identifier>name).text);
}
@@ -8963,7 +9116,7 @@ module ts {
var typeName1 = typeToString(existing.containingType);
var typeName2 = typeToString(base);
var errorInfo = chainDiagnosticMessages(undefined, Diagnostics.Named_properties_0_of_types_1_and_2_are_not_identical, prop.name, typeName1, typeName2);
var errorInfo = chainDiagnosticMessages(undefined, Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2);
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
diagnostics.add(createDiagnosticForNodeFromMessageChain(typeNode, errorInfo));
}
@@ -9450,6 +9603,8 @@ module ts {
return checkForStatement(<ForStatement>node);
case SyntaxKind.ForInStatement:
return checkForInStatement(<ForInStatement>node);
case SyntaxKind.ForOfStatement:
return checkForOfStatement(<ForOfStatement>node);
case SyntaxKind.ContinueStatement:
case SyntaxKind.BreakStatement:
return checkBreakOrContinueStatement(<BreakOrContinueStatement>node);
@@ -9484,10 +9639,10 @@ module ts {
case SyntaxKind.ExportAssignment:
return checkExportAssignment(<ExportAssignment>node);
case SyntaxKind.EmptyStatement:
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
return;
case SyntaxKind.DebuggerStatement:
checkGrammarForStatementInAmbientContext(node);
checkGrammarStatementInAmbientContext(node);
return;
}
}
@@ -9559,6 +9714,7 @@ module ts {
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.ContinueStatement:
case SyntaxKind.BreakStatement:
case SyntaxKind.ReturnStatement:
@@ -9755,6 +9911,7 @@ module ts {
case SyntaxKind.NumberKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
return true;
case SyntaxKind.VoidKeyword:
return node.parent.kind !== SyntaxKind.VoidExpression;
@@ -10279,7 +10436,7 @@ module ts {
getSymbolLinks(unknownSymbol).type = unknownType;
globals[undefinedSymbol.name] = undefinedSymbol;
// Initialize special types
globalArraySymbol = getGlobalSymbol("Array");
globalArraySymbol = getGlobalTypeSymbol("Array");
globalArrayType = getTypeOfGlobalSymbol(globalArraySymbol, 1);
globalObjectType = getGlobalType("Object");
globalFunctionType = getGlobalType("Function");
@@ -10287,11 +10444,24 @@ module ts {
globalNumberType = getGlobalType("Number");
globalBooleanType = getGlobalType("Boolean");
globalRegExpType = getGlobalType("RegExp");
// If we're in ES6 mode, load the TemplateStringsArray.
// Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios.
globalTemplateStringsArrayType = languageVersion >= ScriptTarget.ES6
? getGlobalType("TemplateStringsArray")
: unknownType;
if (languageVersion >= ScriptTarget.ES6) {
globalTemplateStringsArrayType = getGlobalType("TemplateStringsArray");
globalESSymbolType = getGlobalType("Symbol");
globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol");
}
else {
globalTemplateStringsArrayType = unknownType;
// Consider putting Symbol interface in lib.d.ts. On the plus side, putting it in lib.d.ts would make it
// extensible for Polyfilling Symbols. But putting it into lib.d.ts could also break users that have
// a global Symbol already, particularly if it is a class.
globalESSymbolType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
globalESSymbolConstructorSymbol = undefined;
}
anyArrayType = createArrayType(anyType);
}
@@ -10506,25 +10676,25 @@ module ts {
return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_exactly_one_parameter);
}
}
else if (parameter.dotDotDotToken) {
if (parameter.dotDotDotToken) {
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
}
else if (parameter.flags & NodeFlags.Modifier) {
if (parameter.flags & NodeFlags.Modifier) {
return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
}
else if (parameter.questionToken) {
if (parameter.questionToken) {
return grammarErrorOnNode(parameter.questionToken, Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
}
else if (parameter.initializer) {
if (parameter.initializer) {
return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
}
else if (!parameter.type) {
if (!parameter.type) {
return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
}
else if (parameter.type.kind !== SyntaxKind.StringKeyword && parameter.type.kind !== SyntaxKind.NumberKeyword) {
if (parameter.type.kind !== SyntaxKind.StringKeyword && parameter.type.kind !== SyntaxKind.NumberKeyword) {
return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number);
}
else if (!node.type) {
if (!node.type) {
return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_a_type_annotation);
}
}
@@ -10755,6 +10925,49 @@ module ts {
}
}
function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInStatement | ForOfStatement): boolean {
if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
return true;
}
if (forInOrOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
var variableList = <VariableDeclarationList>forInOrOfStatement.initializer;
if (!checkGrammarVariableDeclarationList(variableList)) {
if (variableList.declarations.length > 1) {
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
? Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
: Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
}
var firstDeclaration = variableList.declarations[0];
if (firstDeclaration.initializer) {
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
? Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
: Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
return grammarErrorOnNode(firstDeclaration.name, diagnostic);
}
if (firstDeclaration.type) {
var diagnostic = forInOrOfStatement.kind === SyntaxKind.ForInStatement
? Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
: Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
return grammarErrorOnNode(firstDeclaration, diagnostic);
}
}
}
return false;
}
function checkGrammarForOfStatement(forOfStatement: ForOfStatement): boolean {
// Temporarily disallow for-of statements until type check work is complete.
return grammarErrorOnFirstToken(forOfStatement, Diagnostics.for_of_statements_are_not_currently_supported);
if (languageVersion < ScriptTarget.ES6) {
return grammarErrorOnFirstToken(forOfStatement, Diagnostics.for_of_statements_are_only_available_when_targeting_ECMAScript_6_or_higher);
}
return checkGrammarForInOrForOfStatement(forOfStatement);
}
function checkGrammarAccessor(accessor: MethodDeclaration): boolean {
var kind = accessor.kind;
if (languageVersion < ScriptTarget.ES5) {
@@ -10797,8 +11010,8 @@ module ts {
}
}
function checkGrammarForDisallowedComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
if (node.kind === SyntaxKind.ComputedPropertyName) {
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
if (node.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically((<ComputedPropertyName>node).expression)) {
return grammarErrorOnNode(node, message);
}
}
@@ -10829,17 +11042,17 @@ module ts {
// and accessors are not allowed in ambient contexts in general,
// so this error only really matters for methods.
if (isInAmbientContext(node)) {
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_an_ambient_context);
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol);
}
else if (!node.body) {
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_method_overloads);
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol);
}
}
else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) {
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_interfaces);
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol);
}
else if (node.parent.kind === SyntaxKind.TypeLiteral) {
return checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_type_literals);
return checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol);
}
}
@@ -10847,6 +11060,7 @@ module ts {
switch (node.kind) {
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.DoStatement:
case SyntaxKind.WhileStatement:
return true;
@@ -11003,6 +11217,7 @@ module ts {
case SyntaxKind.WithStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
return false;
case SyntaxKind.LabeledStatement:
return allowLetAndConstDeclarations(parent.parent);
@@ -11053,6 +11268,9 @@ module ts {
var inAmbientContext = isInAmbientContext(enumDecl);
for (var i = 0, n = enumDecl.members.length; i < n; i++) {
var node = enumDecl.members[i];
// Do not use hasDynamicName here, because that returns false for well known symbols.
// We want to perform checkComputedPropertyName for all computed properties, including
// well known symbols.
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
hasError = grammarErrorOnNode(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums);
}
@@ -11133,17 +11351,17 @@ module ts {
function checkGrammarProperty(node: PropertyDeclaration) {
if (node.parent.kind === SyntaxKind.ClassDeclaration) {
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional) ||
checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_class_property_declarations)) {
checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) {
return true;
}
}
else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) {
if (checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_interfaces)) {
if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol)) {
return true;
}
}
else if (node.parent.kind === SyntaxKind.TypeLiteral) {
if (checkGrammarForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_type_literals)) {
if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol)) {
return true;
}
}
@@ -11190,7 +11408,7 @@ module ts {
return isInAmbientContext(node) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
}
function checkGrammarForStatementInAmbientContext(node: Node): boolean {
function checkGrammarStatementInAmbientContext(node: Node): boolean {
if (isInAmbientContext(node)) {
// An accessors is already reported about the ambient context
if (isAccessor(node.parent.kind)) {
@@ -123,12 +123,12 @@ module ts {
An_object_member_cannot_be_declared_optional: { code: 1162, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." },
yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." },
Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in enums." },
Computed_property_names_are_not_allowed_in_an_ambient_context: { code: 1165, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in an ambient context." },
Computed_property_names_are_not_allowed_in_class_property_declarations: { code: 1166, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in class property declarations." },
A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: DiagnosticCategory.Error, key: "A computed property name in an ambient context must directly refer to a built-in symbol." },
A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: { code: 1166, category: DiagnosticCategory.Error, key: "A computed property name in a class property declaration must directly refer to a built-in symbol." },
Computed_property_names_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1167, category: DiagnosticCategory.Error, key: "Computed property names are only available when targeting ECMAScript 6 and higher." },
Computed_property_names_are_not_allowed_in_method_overloads: { code: 1168, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in method overloads." },
Computed_property_names_are_not_allowed_in_interfaces: { code: 1169, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in interfaces." },
Computed_property_names_are_not_allowed_in_type_literals: { code: 1170, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in type literals." },
A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol: { code: 1168, category: DiagnosticCategory.Error, key: "A computed property name in a method overload must directly refer to a built-in symbol." },
A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol: { code: 1169, category: DiagnosticCategory.Error, key: "A computed property name in an interface must directly refer to a built-in symbol." },
A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol: { code: 1170, category: DiagnosticCategory.Error, key: "A computed property name in a type literal must directly refer to a built-in symbol." },
A_comma_expression_is_not_allowed_in_a_computed_property_name: { code: 1171, category: DiagnosticCategory.Error, key: "A comma expression is not allowed in a computed property name." },
extends_clause_already_seen: { code: 1172, category: DiagnosticCategory.Error, key: "'extends' clause already seen." },
extends_clause_must_precede_implements_clause: { code: 1173, category: DiagnosticCategory.Error, key: "'extends' clause must precede 'implements' clause." },
@@ -147,6 +147,9 @@ module ts {
Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." },
A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." },
A_parameter_property_may_not_be_a_binding_pattern: { code: 1187, category: DiagnosticCategory.Error, key: "A parameter property may not be a binding pattern." },
Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: { code: 1188, category: DiagnosticCategory.Error, key: "Only a single variable declaration is allowed in a 'for...of' statement." },
The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: { code: 1189, category: DiagnosticCategory.Error, key: "The variable declaration of a 'for...in' statement cannot have an initializer." },
The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: { code: 1190, category: DiagnosticCategory.Error, key: "The variable declaration of a 'for...of' statement cannot have an initializer." },
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
@@ -166,7 +169,7 @@ module ts {
Global_type_0_must_be_a_class_or_interface_type: { code: 2316, category: DiagnosticCategory.Error, key: "Global type '{0}' must be a class or interface type." },
Global_type_0_must_have_1_type_parameter_s: { code: 2317, category: DiagnosticCategory.Error, key: "Global type '{0}' must have {1} type parameter(s)." },
Cannot_find_global_type_0: { code: 2318, category: DiagnosticCategory.Error, key: "Cannot find global type '{0}'." },
Named_properties_0_of_types_1_and_2_are_not_identical: { code: 2319, category: DiagnosticCategory.Error, key: "Named properties '{0}' of types '{1}' and '{2}' are not identical." },
Named_property_0_of_types_1_and_2_are_not_identical: { code: 2319, category: DiagnosticCategory.Error, key: "Named property '{0}' of types '{1}' and '{2}' are not identical." },
Interface_0_cannot_simultaneously_extend_types_1_and_2: { code: 2320, category: DiagnosticCategory.Error, key: "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'." },
Excessive_stack_depth_comparing_types_0_and_1: { code: 2321, category: DiagnosticCategory.Error, key: "Excessive stack depth comparing types '{0}' and '{1}'." },
Type_0_is_not_assignable_to_type_1: { code: 2322, category: DiagnosticCategory.Error, key: "Type '{0}' is not assignable to type '{1}'." },
@@ -188,7 +191,7 @@ module ts {
Property_0_does_not_exist_on_type_1: { code: 2339, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on type '{1}'." },
Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: { code: 2340, category: DiagnosticCategory.Error, key: "Only public and protected methods of the base class are accessible via the 'super' keyword" },
Property_0_is_private_and_only_accessible_within_class_1: { code: 2341, category: DiagnosticCategory.Error, key: "Property '{0}' is private and only accessible within class '{1}'." },
An_index_expression_argument_must_be_of_type_string_number_or_any: { code: 2342, category: DiagnosticCategory.Error, key: "An index expression argument must be of type 'string', 'number', or 'any'." },
An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: { code: 2342, category: DiagnosticCategory.Error, key: "An index expression argument must be of type 'string', 'number', 'symbol, or 'any'." },
Type_0_does_not_satisfy_the_constraint_1: { code: 2344, category: DiagnosticCategory.Error, key: "Type '{0}' does not satisfy the constraint '{1}'." },
Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: { code: 2345, category: DiagnosticCategory.Error, key: "Argument of type '{0}' is not assignable to parameter of type '{1}'." },
Supplied_parameters_do_not_match_any_signature_of_call_target: { code: 2346, category: DiagnosticCategory.Error, key: "Supplied parameters do not match any signature of call target." },
@@ -204,7 +207,7 @@ module ts {
The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer: { code: 2357, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator must be a variable, property or indexer." },
The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2358, category: DiagnosticCategory.Error, key: "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter." },
The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: { code: 2359, category: DiagnosticCategory.Error, key: "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type." },
The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number: { code: 2360, category: DiagnosticCategory.Error, key: "The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'." },
The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: { code: 2360, category: DiagnosticCategory.Error, key: "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'." },
The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2361, category: DiagnosticCategory.Error, key: "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter" },
The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2362, category: DiagnosticCategory.Error, key: "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2363, category: DiagnosticCategory.Error, key: "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
@@ -299,20 +302,26 @@ module ts {
Type_0_is_not_an_array_type: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." },
A_rest_element_must_be_last_in_an_array_destructuring_pattern: { code: 2462, category: DiagnosticCategory.Error, key: "A rest element must be last in an array destructuring pattern" },
A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: { code: 2463, category: DiagnosticCategory.Error, key: "A binding pattern parameter cannot be optional in an implementation signature." },
A_computed_property_name_must_be_of_type_string_number_or_any: { code: 2464, category: DiagnosticCategory.Error, key: "A computed property name must be of type 'string', 'number', or 'any'." },
A_computed_property_name_must_be_of_type_string_number_symbol_or_any: { code: 2464, category: DiagnosticCategory.Error, key: "A computed property name must be of type 'string', 'number', 'symbol', or 'any'." },
this_cannot_be_referenced_in_a_computed_property_name: { code: 2465, category: DiagnosticCategory.Error, key: "'this' cannot be referenced in a computed property name." },
super_cannot_be_referenced_in_a_computed_property_name: { code: 2466, category: DiagnosticCategory.Error, key: "'super' cannot be referenced in a computed property name." },
A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: { code: 2466, category: DiagnosticCategory.Error, key: "A computed property name cannot reference a type parameter from its containing type." },
Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2468, category: DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." },
Enum_declarations_must_all_be_const_or_non_const: { code: 2469, category: DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." },
In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2470, category: DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." },
const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2471, category: DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." },
A_const_enum_member_can_only_be_accessed_using_a_string_literal: { code: 2472, category: DiagnosticCategory.Error, key: "A const enum member can only be accessed using a string literal." },
const_enum_member_initializer_was_evaluated_to_a_non_finite_value: { code: 2473, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to a non-finite value." },
const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: { code: 2474, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to disallowed value 'NaN'." },
Property_0_does_not_exist_on_const_enum_1: { code: 2475, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on 'const' enum '{1}'." },
let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 2476, category: DiagnosticCategory.Error, key: "'let' is not allowed to be used as a name in 'let' or 'const' declarations." },
Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: { code: 2477, category: DiagnosticCategory.Error, key: "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'." },
A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: { code: 2467, category: DiagnosticCategory.Error, key: "A computed property name cannot reference a type parameter from its containing type." },
Cannot_find_global_value_0: { code: 2468, category: DiagnosticCategory.Error, key: "Cannot find global value '{0}'." },
The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to type 'symbol'." },
Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: DiagnosticCategory.Error, key: "'Symbol' reference does not refer to the global Symbol constructor object." },
A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: DiagnosticCategory.Error, key: "A computed property name of the form '{0}' must be of type 'symbol'." },
Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2472, category: DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." },
Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." },
In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." },
const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." },
A_const_enum_member_can_only_be_accessed_using_a_string_literal: { code: 2476, category: DiagnosticCategory.Error, key: "A const enum member can only be accessed using a string literal." },
const_enum_member_initializer_was_evaluated_to_a_non_finite_value: { code: 2477, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to a non-finite value." },
const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: { code: 2478, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to disallowed value 'NaN'." },
Property_0_does_not_exist_on_const_enum_1: { code: 2479, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on 'const' enum '{1}'." },
let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 2480, category: DiagnosticCategory.Error, key: "'let' is not allowed to be used as a name in 'let' or 'const' declarations." },
Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: { code: 2481, category: DiagnosticCategory.Error, key: "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'." },
for_of_statements_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 2482, category: DiagnosticCategory.Error, key: "'for...of' statements are only available when targeting ECMAScript 6 or higher." },
The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: { code: 2483, category: DiagnosticCategory.Error, key: "The left-hand side of a 'for...of' statement cannot use a type annotation." },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
@@ -458,5 +467,6 @@ module ts {
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression: { code: 9002, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression." },
for_of_statements_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'for...of' statements are not currently supported." },
};
}
+61 -21
View File
@@ -483,11 +483,11 @@
"category": "Error",
"code": 1164
},
"Computed property names are not allowed in an ambient context.": {
"A computed property name in an ambient context must directly refer to a built-in symbol.": {
"category": "Error",
"code": 1165
},
"Computed property names are not allowed in class property declarations.": {
"A computed property name in a class property declaration must directly refer to a built-in symbol.": {
"category": "Error",
"code": 1166
},
@@ -495,15 +495,15 @@
"category": "Error",
"code": 1167
},
"Computed property names are not allowed in method overloads.": {
"A computed property name in a method overload must directly refer to a built-in symbol.": {
"category": "Error",
"code": 1168
},
"Computed property names are not allowed in interfaces.": {
"A computed property name in an interface must directly refer to a built-in symbol.": {
"category": "Error",
"code": 1169
},
"Computed property names are not allowed in type literals.": {
"A computed property name in a type literal must directly refer to a built-in symbol.": {
"category": "Error",
"code": 1170
},
@@ -579,6 +579,18 @@
"category": "Error",
"code": 1187
},
"Only a single variable declaration is allowed in a 'for...of' statement.": {
"category": "Error",
"code": 1188
},
"The variable declaration of a 'for...in' statement cannot have an initializer.": {
"category": "Error",
"code": 1189
},
"The variable declaration of a 'for...of' statement cannot have an initializer.": {
"category": "Error",
"code": 1190
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@@ -656,7 +668,7 @@
"category": "Error",
"code": 2318
},
"Named properties '{0}' of types '{1}' and '{2}' are not identical.": {
"Named property '{0}' of types '{1}' and '{2}' are not identical.": {
"category": "Error",
"code": 2319
},
@@ -744,7 +756,7 @@
"category": "Error",
"code": 2341
},
"An index expression argument must be of type 'string', 'number', or 'any'.": {
"An index expression argument must be of type 'string', 'number', 'symbol, or 'any'.": {
"category": "Error",
"code": 2342
},
@@ -808,7 +820,7 @@
"category": "Error",
"code": 2359
},
"The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'.": {
"The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.": {
"category": "Error",
"code": 2360
},
@@ -1188,7 +1200,7 @@
"category": "Error",
"code": 2463
},
"A computed property name must be of type 'string', 'number', or 'any'.": {
"A computed property name must be of type 'string', 'number', 'symbol', or 'any'.": {
"category": "Error",
"code": 2464
},
@@ -1202,48 +1214,72 @@
},
"A computed property name cannot reference a type parameter from its containing type.": {
"category": "Error",
"code": 2466
"code": 2467
},
"Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher.": {
"Cannot find global value '{0}'.": {
"category": "Error",
"code": 2468
},
"Enum declarations must all be const or non-const.": {
"The '{0}' operator cannot be applied to type 'symbol'.": {
"category": "Error",
"code": 2469
},
"In 'const' enum declarations member initializer must be constant expression.": {
"'Symbol' reference does not refer to the global Symbol constructor object.": {
"category": "Error",
"code": 2470
},
"'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": {
"A computed property name of the form '{0}' must be of type 'symbol'.": {
"category": "Error",
"code": 2471
},
"A const enum member can only be accessed using a string literal.": {
"Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher.": {
"category": "Error",
"code": 2472
},
"'const' enum member initializer was evaluated to a non-finite value.": {
"Enum declarations must all be const or non-const.": {
"category": "Error",
"code": 2473
},
"'const' enum member initializer was evaluated to disallowed value 'NaN'.": {
"In 'const' enum declarations member initializer must be constant expression.": {
"category": "Error",
"code": 2474
},
"Property '{0}' does not exist on 'const' enum '{1}'.": {
"'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": {
"category": "Error",
"code": 2475
},
"'let' is not allowed to be used as a name in 'let' or 'const' declarations.": {
"A const enum member can only be accessed using a string literal.": {
"category": "Error",
"code": 2476
},
"Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.": {
"'const' enum member initializer was evaluated to a non-finite value.": {
"category": "Error",
"code": 2477
},
"'const' enum member initializer was evaluated to disallowed value 'NaN'.": {
"category": "Error",
"code": 2478
},
"Property '{0}' does not exist on 'const' enum '{1}'.": {
"category": "Error",
"code": 2479
},
"'let' is not allowed to be used as a name in 'let' or 'const' declarations.": {
"category": "Error",
"code": 2480
},
"Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.": {
"category": "Error",
"code": 2481
},
"'for...of' statements are only available when targeting ECMAScript 6 or higher.": {
"category": "Error",
"code": 2482
},
"The left-hand side of a 'for...of' statement cannot use a type annotation.": {
"category": "Error",
"code": 2483
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@@ -1520,7 +1556,7 @@
"Exported type alias '{0}' has or is using private name '{1}'.": {
"category": "Error",
"code": 4081
},
},
"The current host does not support the '{0}' option.": {
"category": "Error",
"code": 5001
@@ -1825,5 +1861,9 @@
"The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression.": {
"category": "Error",
"code": 9002
},
"'for...of' statements are not currently supported.": {
"category": "Error",
"code": 9003
}
}
+26 -15
View File
@@ -276,7 +276,7 @@ module ts {
var firstAccessor: AccessorDeclaration;
var getAccessor: AccessorDeclaration;
var setAccessor: AccessorDeclaration;
if (accessor.name.kind === SyntaxKind.ComputedPropertyName) {
if (hasDynamicName(accessor)) {
firstAccessor = accessor;
if (accessor.kind === SyntaxKind.GetAccessor) {
getAccessor = accessor;
@@ -290,19 +290,22 @@ module ts {
}
else {
forEach(node.members,(member: Declaration) => {
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor) &&
(<Identifier>member.name).text === (<Identifier>accessor.name).text &&
(member.flags & NodeFlags.Static) === (accessor.flags & NodeFlags.Static)) {
if (!firstAccessor) {
firstAccessor = <AccessorDeclaration>member;
}
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
&& (member.flags & NodeFlags.Static) === (accessor.flags & NodeFlags.Static)) {
var memberName = getPropertyNameForPropertyNameNode(member.name);
var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
if (memberName === accessorName) {
if (!firstAccessor) {
firstAccessor = <AccessorDeclaration>member;
}
if (member.kind === SyntaxKind.GetAccessor && !getAccessor) {
getAccessor = <AccessorDeclaration>member;
}
if (member.kind === SyntaxKind.GetAccessor && !getAccessor) {
getAccessor = <AccessorDeclaration>member;
}
if (member.kind === SyntaxKind.SetAccessor && !setAccessor) {
setAccessor = <AccessorDeclaration>member;
if (member.kind === SyntaxKind.SetAccessor && !setAccessor) {
setAccessor = <AccessorDeclaration>member;
}
}
}
});
@@ -580,6 +583,7 @@ module ts {
case SyntaxKind.StringKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.StringLiteral:
return writeTextOfNode(currentSourceFile, type);
@@ -2917,7 +2921,7 @@ module ts {
emitEmbeddedStatement(node.statement);
}
function emitForInStatement(node: ForInStatement) {
function emitForInOrForOfStatement(node: ForInStatement | ForOfStatement) {
var endPos = emitToken(SyntaxKind.ForKeyword, node.pos);
write(" ");
endPos = emitToken(SyntaxKind.OpenParenToken, endPos);
@@ -2938,7 +2942,13 @@ module ts {
else {
emit(node.initializer);
}
write(" in ");
if (node.kind === SyntaxKind.ForInStatement) {
write(" in ");
}
else {
write(" of ");
}
emit(node.expression);
emitToken(SyntaxKind.CloseParenToken, node.expression.end);
emitEmbeddedStatement(node.statement);
@@ -4357,8 +4367,9 @@ module ts {
return emitWhileStatement(<WhileStatement>node);
case SyntaxKind.ForStatement:
return emitForStatement(<ForStatement>node);
case SyntaxKind.ForOfStatement:
case SyntaxKind.ForInStatement:
return emitForInStatement(<ForInStatement>node);
return emitForInOrForOfStatement(<ForInStatement>node);
case SyntaxKind.ContinueStatement:
case SyntaxKind.BreakStatement:
return emitBreakOrContinueStatement(<BreakOrContinueStatement>node);
+56 -18
View File
@@ -191,6 +191,10 @@ module ts {
return visitNode(cbNode, (<ForInStatement>node).initializer) ||
visitNode(cbNode, (<ForInStatement>node).expression) ||
visitNode(cbNode, (<ForInStatement>node).statement);
case SyntaxKind.ForOfStatement:
return visitNode(cbNode, (<ForOfStatement>node).initializer) ||
visitNode(cbNode, (<ForOfStatement>node).expression) ||
visitNode(cbNode, (<ForOfStatement>node).statement);
case SyntaxKind.ContinueStatement:
case SyntaxKind.BreakStatement:
return visitNode(cbNode, (<BreakOrContinueStatement>node).label);
@@ -1598,8 +1602,8 @@ module ts {
}
// in the case where we're parsing the variable declarator of a 'for-in' statement, we
// are done if we see an 'in' keyword in front of us.
if (token === SyntaxKind.InKeyword) {
// are done if we see an 'in' keyword in front of us. Same with for-of
if (isInOrOfKeyword(token)) {
return true;
}
@@ -1877,6 +1881,7 @@ module ts {
case SyntaxKind.BreakStatement:
case SyntaxKind.ContinueStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.WhileStatement:
case SyntaxKind.WithStatement:
@@ -2593,6 +2598,7 @@ module ts {
case SyntaxKind.StringKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
// If these are followed by a dot, then parse these out as a dotted type reference instead.
var node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReference();
@@ -2617,6 +2623,7 @@ module ts {
case SyntaxKind.StringKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.TypeOfKeyword:
case SyntaxKind.OpenBraceToken:
@@ -3159,6 +3166,10 @@ module ts {
return parseBinaryExpressionRest(precedence, leftOperand);
}
function isInOrOfKeyword(t: SyntaxKind) {
return t === SyntaxKind.InKeyword || t === SyntaxKind.OfKeyword;
}
function parseBinaryExpressionRest(precedence: number, leftOperand: Expression): Expression {
while (true) {
// We either have a binary operator here, or we're finished. We call
@@ -3788,7 +3799,7 @@ module ts {
return finishNode(node);
}
function parseForOrForInStatement(): Statement {
function parseForOrForInOrForOfStatement(): Statement {
var pos = getNodePos();
parseExpected(SyntaxKind.ForKeyword);
parseExpected(SyntaxKind.OpenParenToken);
@@ -3796,21 +3807,27 @@ module ts {
var initializer: VariableDeclarationList | Expression = undefined;
if (token !== SyntaxKind.SemicolonToken) {
if (token === SyntaxKind.VarKeyword || token === SyntaxKind.LetKeyword || token === SyntaxKind.ConstKeyword) {
initializer = parseVariableDeclarationList(/*disallowIn:*/ true);
initializer = parseVariableDeclarationList(/*inForStatementInitializer:*/ true);
}
else {
initializer = disallowInAnd(parseExpression);
}
}
var forOrForInStatement: IterationStatement;
var forOrForInOrForOfStatement: IterationStatement;
if (parseOptional(SyntaxKind.InKeyword)) {
var forInStatement = <ForInStatement>createNode(SyntaxKind.ForInStatement, pos);
forInStatement.initializer = initializer;
forInStatement.expression = allowInAnd(parseExpression);
parseExpected(SyntaxKind.CloseParenToken);
forOrForInStatement = forInStatement;
forOrForInOrForOfStatement = forInStatement;
}
else {
else if (parseOptional(SyntaxKind.OfKeyword)) {
var forOfStatement = <ForOfStatement>createNode(SyntaxKind.ForOfStatement, pos);
forOfStatement.initializer = initializer;
forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
parseExpected(SyntaxKind.CloseParenToken);
forOrForInOrForOfStatement = forOfStatement;
} else {
var forStatement = <ForStatement>createNode(SyntaxKind.ForStatement, pos);
forStatement.initializer = initializer;
parseExpected(SyntaxKind.SemicolonToken);
@@ -3822,12 +3839,12 @@ module ts {
forStatement.iterator = allowInAnd(parseExpression);
}
parseExpected(SyntaxKind.CloseParenToken);
forOrForInStatement = forStatement;
forOrForInOrForOfStatement = forStatement;
}
forOrForInStatement.statement = parseStatement();
forOrForInOrForOfStatement.statement = parseStatement();
return finishNode(forOrForInStatement);
return finishNode(forOrForInOrForOfStatement);
}
function parseBreakOrContinueStatement(kind: SyntaxKind): BreakOrContinueStatement {
@@ -4073,7 +4090,7 @@ module ts {
case SyntaxKind.WhileKeyword:
return parseWhileStatement();
case SyntaxKind.ForKeyword:
return parseForOrForInStatement();
return parseForOrForInOrForOfStatement();
case SyntaxKind.ContinueKeyword:
return parseBreakOrContinueStatement(SyntaxKind.ContinueStatement);
case SyntaxKind.BreakKeyword:
@@ -4215,11 +4232,13 @@ module ts {
var node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
node.name = parseIdentifierOrPattern();
node.type = parseTypeAnnotation();
node.initializer = parseInitializer(/*inParameter*/ false);
if (!isInOrOfKeyword(token)) {
node.initializer = parseInitializer(/*inParameter*/ false);
}
return finishNode(node);
}
function parseVariableDeclarationList(disallowIn: boolean): VariableDeclarationList {
function parseVariableDeclarationList(inForStatementInitializer: boolean): VariableDeclarationList {
var node = <VariableDeclarationList>createNode(SyntaxKind.VariableDeclarationList);
switch (token) {
@@ -4236,20 +4255,39 @@ module ts {
}
nextToken();
var savedDisallowIn = inDisallowInContext();
setDisallowInContext(disallowIn);
node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations, parseVariableDeclaration);
// The user may have written the following:
//
// for (var of X) { }
//
// In this case, we want to parse an empty declaration list, and then parse 'of'
// as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
// So we need to look ahead to determine if 'of' should be treated as a keyword in
// this context.
// The checker will then give an error that there is an empty declaration list.
if (token === SyntaxKind.OfKeyword && lookAhead(canFollowContextualOfKeyword)) {
node.declarations = createMissingList<VariableDeclaration>();
}
else {
var savedDisallowIn = inDisallowInContext();
setDisallowInContext(inForStatementInitializer);
setDisallowInContext(savedDisallowIn);
node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations, parseVariableDeclaration);
setDisallowInContext(savedDisallowIn);
}
return finishNode(node);
}
function canFollowContextualOfKeyword(): boolean {
return nextTokenIsIdentifier() && nextToken() === SyntaxKind.CloseParenToken;
}
function parseVariableStatement(fullStart: number, modifiers: ModifiersArray): VariableStatement {
var node = <VariableStatement>createNode(SyntaxKind.VariableStatement, fullStart);
setModifiers(node, modifiers);
node.declarationList = parseVariableDeclarationList(/*disallowIn:*/ false);
node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer:*/ false);
parseSemicolon();
return finishNode(node);
}
+2
View File
@@ -82,6 +82,7 @@ module ts {
"string": SyntaxKind.StringKeyword,
"super": SyntaxKind.SuperKeyword,
"switch": SyntaxKind.SwitchKeyword,
"symbol": SyntaxKind.SymbolKeyword,
"this": SyntaxKind.ThisKeyword,
"throw": SyntaxKind.ThrowKeyword,
"true": SyntaxKind.TrueKeyword,
@@ -93,6 +94,7 @@ module ts {
"while": SyntaxKind.WhileKeyword,
"with": SyntaxKind.WithKeyword,
"yield": SyntaxKind.YieldKeyword,
"of": SyntaxKind.OfKeyword,
"{": SyntaxKind.OpenBraceToken,
"}": SyntaxKind.CloseBraceToken,
"(": SyntaxKind.OpenParenToken,
+13 -5
View File
@@ -140,8 +140,9 @@ module ts {
NumberKeyword,
SetKeyword,
StringKeyword,
SymbolKeyword,
TypeKeyword,
OfKeyword, // LastKeyword and LastToken
// Parse tree nodes
// Names
@@ -210,6 +211,7 @@ module ts {
WhileStatement,
ForStatement,
ForInStatement,
ForOfStatement,
ContinueStatement,
BreakStatement,
ReturnStatement,
@@ -259,7 +261,7 @@ module ts {
FirstReservedWord = BreakKeyword,
LastReservedWord = WithKeyword,
FirstKeyword = BreakKeyword,
LastKeyword = TypeKeyword,
LastKeyword = OfKeyword,
FirstFutureReservedWord = ImplementsKeyword,
LastFutureReservedWord = YieldKeyword,
FirstTypeNode = TypeReference,
@@ -267,7 +269,7 @@ module ts {
FirstPunctuation = OpenBraceToken,
LastPunctuation = CaretEqualsToken,
FirstToken = Unknown,
LastToken = TypeKeyword,
LastToken = OfKeyword,
FirstTriviaToken = SingleLineCommentTrivia,
LastTriviaToken = ConflictMarkerTrivia,
FirstLiteralToken = NumericLiteral,
@@ -752,6 +754,11 @@ module ts {
expression: Expression;
}
export interface ForOfStatement extends IterationStatement {
initializer: VariableDeclarationList | Expression;
expression: Expression;
}
export interface BreakOrContinueStatement extends Statement {
label?: Identifier;
}
@@ -1298,9 +1305,10 @@ module ts {
ObjectLiteral = 0x00020000, // Originates in an object literal
ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type
ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type
ESSymbol = 0x00100000, // Type of symbol primitive introduced in ES6
Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null,
Primitive = String | Number | Boolean | Void | Undefined | Null | StringLiteral | Enum,
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
Primitive = String | Number | Boolean | ESSymbol | Void | Undefined | Null | StringLiteral | Enum,
StringLike = String | StringLiteral,
NumberLike = Number | Enum,
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
+52 -1
View File
@@ -348,6 +348,7 @@ module ts {
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.WithStatement:
case SyntaxKind.SwitchStatement:
case SyntaxKind.CaseClause:
@@ -565,7 +566,8 @@ module ts {
forStatement.condition === node ||
forStatement.iterator === node;
case SyntaxKind.ForInStatement:
var forInStatement = <ForInStatement>parent;
case SyntaxKind.ForOfStatement:
var forInStatement = <ForInStatement | ForOfStatement>parent;
return (forInStatement.initializer === node && forInStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) ||
forInStatement.expression === node;
case SyntaxKind.TypeAssertionExpression:
@@ -693,6 +695,7 @@ module ts {
case SyntaxKind.ExpressionStatement:
case SyntaxKind.EmptyStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.IfStatement:
case SyntaxKind.LabeledStatement:
@@ -840,6 +843,54 @@ module ts {
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
}
/**
* A declaration has a dynamic name if both of the following are true:
* 1. The declaration has a computed property name
* 2. The computed name is *not* expressed as Symbol.<name>, where name
* is a property of the Symbol constructor that denotes a built in
* Symbol.
*/
export function hasDynamicName(declaration: Declaration): boolean {
return declaration.name &&
declaration.name.kind === SyntaxKind.ComputedPropertyName &&
!isWellKnownSymbolSyntactically((<ComputedPropertyName>declaration.name).expression);
}
/**
* Checks if the expression is of the form:
* Symbol.name
* where Symbol is literally the word "Symbol", and name is any identifierName
*/
export function isWellKnownSymbolSyntactically(node: Expression): boolean {
return node.kind === SyntaxKind.PropertyAccessExpression && isESSymbolIdentifier((<PropertyAccessExpression>node).expression);
}
export function getPropertyNameForPropertyNameNode(name: DeclarationName): string {
if (name.kind === SyntaxKind.Identifier || name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral) {
return (<Identifier | LiteralExpression>name).text;
}
if (name.kind === SyntaxKind.ComputedPropertyName) {
var nameExpression = (<ComputedPropertyName>name).expression;
if (isWellKnownSymbolSyntactically(nameExpression)) {
var rightHandSideName = (<PropertyAccessExpression>nameExpression).name.text;
return getPropertyNameForKnownSymbolName(rightHandSideName);
}
}
return undefined;
}
export function getPropertyNameForKnownSymbolName(symbolName: string): string {
return "__@" + symbolName;
}
/**
* Includes the word "Symbol" with unicode escapes
*/
export function isESSymbolIdentifier(node: Node): boolean {
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
}
export function isModifier(token: SyntaxKind): boolean {
switch (token) {
case SyntaxKind.PublicKeyword: