Merge branch 'master' into testPerf

Conflicts:
	Jakefile.js
	src/compiler/program.ts
	src/compiler/types.ts
	src/harness/harness.ts
	src/harness/projectsRunner.ts
	src/harness/runner.ts
This commit is contained in:
Daniel Rosenwasser
2015-06-08 14:45:38 -07:00
137 changed files with 3308 additions and 1700 deletions
+147 -131
View File
@@ -1493,8 +1493,9 @@ module ts {
// Write undefined/null type as any
if (type.flags & TypeFlags.Intrinsic) {
// Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving
writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) &&
(type.flags & TypeFlags.Any) ? "any" : (<IntrinsicType>type).intrinsicName);
writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type)
? "any"
: (<IntrinsicType>type).intrinsicName);
}
else if (type.flags & TypeFlags.Reference) {
writeTypeReference(<TypeReference>type, flags);
@@ -2136,6 +2137,10 @@ module ts {
return prop ? getTypeOfSymbol(prop) : undefined;
}
function isTypeAny(type: Type) {
return type && (type.flags & TypeFlags.Any) !== 0;
}
// Return the inferred type for a binding element
function getTypeForBindingElement(declaration: BindingElement): Type {
let pattern = <BindingPattern>declaration.parent;
@@ -2147,7 +2152,7 @@ module ts {
// If no type was specified or inferred for parent, or if the specified or inferred type is any,
// infer from the initializer of the binding element if one is present. Otherwise, go with the
// undefined or any type of the parent.
if (!parentType || parentType === anyType) {
if (!parentType || isTypeAny(parentType)) {
if (declaration.initializer) {
return checkExpressionCached(declaration.initializer);
}
@@ -2174,7 +2179,7 @@ module ts {
// fact an iterable or array (depending on target language).
let elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false);
if (!declaration.dotDotDotToken) {
if (elementType.flags & TypeFlags.Any) {
if (isTypeAny(elementType)) {
return elementType;
}
@@ -3721,9 +3726,9 @@ module ts {
}
}
function containsAnyType(types: Type[]) {
function containsTypeAny(types: Type[]) {
for (let type of types) {
if (type.flags & TypeFlags.Any) {
if (isTypeAny(type)) {
return true;
}
}
@@ -3751,7 +3756,7 @@ module ts {
let sortedTypes: Type[] = [];
addTypesToSortedSet(sortedTypes, types);
if (noSubtypeReduction) {
if (containsAnyType(sortedTypes)) {
if (containsTypeAny(sortedTypes)) {
return anyType;
}
removeAllButLast(sortedTypes, undefinedType);
@@ -4175,13 +4180,13 @@ module ts {
// both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
if (source === target) return Ternary.True;
if (relation !== identityRelation) {
if (target.flags & TypeFlags.Any) return Ternary.True;
if (isTypeAny(target)) return Ternary.True;
if (source === undefinedType) return Ternary.True;
if (source === nullType && target !== undefinedType) return Ternary.True;
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
if (relation === assignableRelation) {
if (source.flags & TypeFlags.Any) return Ternary.True;
if (isTypeAny(source)) return Ternary.True;
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
}
}
@@ -5406,55 +5411,58 @@ module ts {
function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) {
let type = getTypeOfSymbol(symbol);
// Only narrow when symbol is variable of type any or an object, union, or type parameter type
if (node && symbol.flags & SymbolFlags.Variable && type.flags & (TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) {
loop: while (node.parent) {
let child = node;
node = node.parent;
let narrowedType = type;
switch (node.kind) {
case SyntaxKind.IfStatement:
// In a branch of an if statement, narrow based on controlling expression
if (child !== (<IfStatement>node).expression) {
narrowedType = narrowType(type, (<IfStatement>node).expression, /*assumeTrue*/ child === (<IfStatement>node).thenStatement);
}
break;
case SyntaxKind.ConditionalExpression:
// In a branch of a conditional expression, narrow based on controlling condition
if (child !== (<ConditionalExpression>node).condition) {
narrowedType = narrowType(type, (<ConditionalExpression>node).condition, /*assumeTrue*/ child === (<ConditionalExpression>node).whenTrue);
}
break;
case SyntaxKind.BinaryExpression:
// In the right operand of an && or ||, narrow based on left operand
if (child === (<BinaryExpression>node).right) {
if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ true);
if (node && symbol.flags & SymbolFlags.Variable) {
if (isTypeAny(type) || type.flags & (TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) {
loop: while (node.parent) {
let child = node;
node = node.parent;
let narrowedType = type;
switch (node.kind) {
case SyntaxKind.IfStatement:
// In a branch of an if statement, narrow based on controlling expression
if (child !== (<IfStatement>node).expression) {
narrowedType = narrowType(type, (<IfStatement>node).expression, /*assumeTrue*/ child === (<IfStatement>node).thenStatement);
}
else if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.BarBarToken) {
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ false);
break;
case SyntaxKind.ConditionalExpression:
// In a branch of a conditional expression, narrow based on controlling condition
if (child !== (<ConditionalExpression>node).condition) {
narrowedType = narrowType(type, (<ConditionalExpression>node).condition, /*assumeTrue*/ child === (<ConditionalExpression>node).whenTrue);
}
break;
case SyntaxKind.BinaryExpression:
// In the right operand of an && or ||, narrow based on left operand
if (child === (<BinaryExpression>node).right) {
if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ true);
}
else if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.BarBarToken) {
narrowedType = narrowType(type, (<BinaryExpression>node).left, /*assumeTrue*/ false);
}
}
break;
case SyntaxKind.SourceFile:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.Constructor:
// Stop at the first containing function or module declaration
break loop;
}
// Use narrowed type if construct contains no assignments to variable
if (narrowedType !== type) {
if (isVariableAssignedWithin(symbol, node)) {
break;
}
break;
case SyntaxKind.SourceFile:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.Constructor:
// Stop at the first containing function or module declaration
break loop;
}
// Use narrowed type if construct contains no assignments to variable
if (narrowedType !== type) {
if (isVariableAssignedWithin(symbol, node)) {
break;
type = narrowedType;
}
type = narrowedType;
}
}
}
return type;
function narrowTypeByEquality(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
@@ -5527,7 +5535,7 @@ module ts {
function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
// Check that type is not any, assumed result is true, and we have variable symbol on the left
if (type.flags & TypeFlags.Any || !assumeTrue || expr.left.kind !== SyntaxKind.Identifier || getResolvedSymbol(<Identifier>expr.left) !== symbol) {
if (isTypeAny(type) || !assumeTrue || expr.left.kind !== SyntaxKind.Identifier || getResolvedSymbol(<Identifier>expr.left) !== symbol) {
return type;
}
// Check that right operand is a function type with a prototype property
@@ -5541,7 +5549,7 @@ module ts {
if (prototypeProperty) {
// Target type is type of the protoype property
let prototypePropertyType = getTypeOfSymbol(prototypeProperty);
if (prototypePropertyType !== anyType) {
if (!isTypeAny(prototypePropertyType)) {
targetType = prototypePropertyType;
}
}
@@ -6302,7 +6310,11 @@ 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 allConstituentTypesHaveKind(checkComputedPropertyName(name), TypeFlags.Any | TypeFlags.NumberLike);
return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), TypeFlags.NumberLike);
}
function isTypeAnyOrAllConstituentTypesHaveKind(type: Type, kind: TypeFlags): boolean {
return isTypeAny(type) || allConstituentTypesHaveKind(type, kind);
}
function isNumericLiteralName(name: string) {
@@ -6337,7 +6349,7 @@ module ts {
// 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 (!allConstituentTypesHaveKind(links.resolvedType, TypeFlags.Any | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) {
error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
}
else {
@@ -6489,39 +6501,39 @@ module ts {
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
let type = checkExpressionOrQualifiedName(left);
if (type === unknownType) return type;
if (type !== anyType) {
let apparentType = getApparentType(getWidenedType(type));
if (apparentType === unknownType) {
// handle cases when type is Type parameter with invalid constraint
return unknownType;
}
let prop = getPropertyOfType(apparentType, right.text);
if (!prop) {
if (right.text) {
error(right, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(right), typeToString(type));
}
return unknownType;
}
getNodeLinks(node).resolvedSymbol = prop;
if (prop.parent && prop.parent.flags & SymbolFlags.Class) {
// TS 1.0 spec (April 2014): 4.8.2
// - In a constructor, instance member function, instance member accessor, or
// instance member variable initializer where this references a derived class instance,
// a super property access is permitted and must specify a public instance member function of the base class.
// - In a static member function or static member accessor
// where this references the constructor function object of a derived class,
// a super property access is permitted and must specify a public static member function of the base class.
if (left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
error(right, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
}
else {
checkClassPropertyAccess(node, left, type, prop);
}
}
return getTypeOfSymbol(prop);
if (isTypeAny(type)) {
return type;
}
return anyType;
let apparentType = getApparentType(getWidenedType(type));
if (apparentType === unknownType) {
// handle cases when type is Type parameter with invalid constraint
return unknownType;
}
let prop = getPropertyOfType(apparentType, right.text);
if (!prop) {
if (right.text) {
error(right, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(right), typeToString(type));
}
return unknownType;
}
getNodeLinks(node).resolvedSymbol = prop;
if (prop.parent && prop.parent.flags & SymbolFlags.Class) {
// TS 1.0 spec (April 2014): 4.8.2
// - In a constructor, instance member function, instance member accessor, or
// instance member variable initializer where this references a derived class instance,
// a super property access is permitted and must specify a public instance member function of the base class.
// - In a static member function or static member accessor
// where this references the constructor function object of a derived class,
// a super property access is permitted and must specify a public static member function of the base class.
if (left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
error(right, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
}
else {
checkClassPropertyAccess(node, left, type, prop);
}
}
return getTypeOfSymbol(prop);
}
function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean {
@@ -6530,7 +6542,7 @@ module ts {
: (<QualifiedName>node).left;
let type = checkExpressionOrQualifiedName(left);
if (type !== unknownType && type !== anyType) {
if (type !== unknownType && !isTypeAny(type)) {
let prop = getPropertyOfType(getWidenedType(type), propertyName);
if (prop && prop.parent && prop.parent.flags & SymbolFlags.Class) {
if (left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
@@ -6603,10 +6615,10 @@ module ts {
}
// Check for compatible indexer types.
if (allConstituentTypesHaveKind(indexType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
// Try to use a number indexer.
if (allConstituentTypesHaveKind(indexType, TypeFlags.Any | TypeFlags.NumberLike)) {
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike)) {
let numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number);
if (numberIndexType) {
return numberIndexType;
@@ -6620,7 +6632,7 @@ module ts {
}
// Fall back to any.
if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && objectType !== anyType) {
if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !isTypeAny(objectType)) {
error(node, Diagnostics.Index_signature_of_object_type_implicitly_has_an_any_type);
}
@@ -7270,8 +7282,10 @@ module ts {
// types are provided for the argument expressions, and the result is always of type Any.
// We exclude union types because we may have a union of function types that happen to have
// no common signatures.
if (funcType === anyType || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
if (node.typeArguments) {
if (isTypeAny(funcType) || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
// The unknownType indicates that an error already occured (and was reported). No
// need to report another error in this case.
if (funcType !== unknownType && node.typeArguments) {
error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
}
return resolveUntypedCall(node);
@@ -7300,15 +7314,6 @@ module ts {
}
let expressionType = checkExpression(node.expression);
// TS 1.0 spec: 4.11
// If ConstructExpr is of type Any, Args can be any argument
// list and the result of the operation is of type Any.
if (expressionType === anyType) {
if (node.typeArguments) {
error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
}
return resolveUntypedCall(node);
}
// If ConstructExpr's apparent type(section 3.8.1) is an object type with one or
// more construct signatures, the expression is processed in the same manner as a
@@ -7321,6 +7326,16 @@ module ts {
return resolveErrorCall(node);
}
// TS 1.0 spec: 4.11
// If ConstructExpr is of type Any, Args can be any argument
// list and the result of the operation is of type Any.
if (isTypeAny(expressionType)) {
if (node.typeArguments) {
error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
}
return resolveUntypedCall(node);
}
// Technically, this signatures list may be incomplete. We are taking the apparent type,
// but we are not including construct signatures that may have been added to the Object or
// Function interface, since they have none by default. This is a bit of a leap of faith
@@ -7358,7 +7373,7 @@ module ts {
let callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
if (tagType === anyType || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) {
if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) {
return resolveUntypedCall(node);
}
@@ -7570,7 +7585,7 @@ module ts {
}
// Functions that return 'void' or 'any' don't need any return expressions.
if (returnType === voidType || returnType === anyType) {
if (returnType === voidType || isTypeAny(returnType)) {
return;
}
@@ -7674,7 +7689,7 @@ module ts {
}
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
if (!allConstituentTypesHaveKind(type, TypeFlags.Any | TypeFlags.NumberLike)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(type, TypeFlags.NumberLike)) {
error(operand, diagnostic);
return false;
}
@@ -7886,7 +7901,7 @@ module ts {
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
if (!(rightType.flags & TypeFlags.Any || isTypeSubtypeOf(rightType, globalFunctionType))) {
if (!(isTypeAny(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) {
error(node.right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
}
return booleanType;
@@ -7897,10 +7912,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 (!allConstituentTypesHaveKind(leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, 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 (!allConstituentTypesHaveKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 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;
@@ -7912,10 +7927,11 @@ module ts {
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
// TODO(andersh): Computed property support
let name = <Identifier>(<PropertyAssignment>p).name;
let type = sourceType.flags & TypeFlags.Any ? sourceType :
getTypeOfPropertyOfType(sourceType, name.text) ||
isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
getIndexTypeOfType(sourceType, IndexKind.String);
let type = isTypeAny(sourceType)
? sourceType
: getTypeOfPropertyOfType(sourceType, name.text) ||
isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
getIndexTypeOfType(sourceType, IndexKind.String);
if (type) {
checkDestructuringAssignment((<PropertyAssignment>p).initializer || name, type);
}
@@ -7941,8 +7957,9 @@ module ts {
if (e.kind !== SyntaxKind.OmittedExpression) {
if (e.kind !== SyntaxKind.SpreadElementExpression) {
let propName = "" + i;
let type = sourceType.flags & TypeFlags.Any ? sourceType :
isTupleLikeType(sourceType)
let type = isTypeAny(sourceType)
? sourceType
: isTupleLikeType(sourceType)
? getTypeOfPropertyOfType(sourceType, propName)
: elementType;
if (type) {
@@ -8081,10 +8098,10 @@ module ts {
// 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) {
else if (isTypeAny(leftType) || isTypeAny(rightType)) {
// 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;
resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType;
}
// Symbols are not allowed at all in arithmetic expressions
@@ -9780,7 +9797,7 @@ module ts {
if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
}
else if (!allConstituentTypesHaveKind(leftType, TypeFlags.Any | TypeFlags.StringLike)) {
else if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike)) {
error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
}
else {
@@ -9792,7 +9809,7 @@ module ts {
let rightType = 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 (!allConstituentTypesHaveKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, 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);
}
@@ -9814,7 +9831,7 @@ module ts {
}
function checkIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean): Type {
if (inputType.flags & TypeFlags.Any) {
if (isTypeAny(inputType)) {
return inputType;
}
@@ -9873,7 +9890,7 @@ module ts {
* whole pattern and that T (above) is 'any'.
*/
function getElementTypeOfIterable(type: Type, errorNode: Node): Type {
if (type.flags & TypeFlags.Any) {
if (isTypeAny(type)) {
return undefined;
}
@@ -9886,7 +9903,7 @@ module ts {
}
else {
let iteratorFunction = getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("iterator"));
if (iteratorFunction && iteratorFunction.flags & TypeFlags.Any) {
if (isTypeAny(iteratorFunction)) {
return undefined;
}
@@ -9919,7 +9936,7 @@ module ts {
*
*/
function getElementTypeOfIterator(type: Type, errorNode: Node): Type {
if (type.flags & TypeFlags.Any) {
if (isTypeAny(type)) {
return undefined;
}
@@ -9932,7 +9949,7 @@ module ts {
}
else {
let iteratorNextFunction = getTypeOfPropertyOfType(type, "next");
if (iteratorNextFunction && iteratorNextFunction.flags & TypeFlags.Any) {
if (isTypeAny(iteratorNextFunction)) {
return undefined;
}
@@ -9945,7 +9962,7 @@ module ts {
}
let iteratorNextResult = getUnionType(map(iteratorNextFunctionSignatures, getReturnTypeOfSignature));
if (iteratorNextResult.flags & TypeFlags.Any) {
if (isTypeAny(iteratorNextResult)) {
return undefined;
}
@@ -9965,7 +9982,7 @@ module ts {
}
function getElementTypeOfIterableIterator(type: Type): Type {
if (type.flags & TypeFlags.Any) {
if (isTypeAny(type)) {
return undefined;
}
@@ -11344,12 +11361,7 @@ module ts {
function checkSourceFile(node: SourceFile) {
let start = new Date().getTime();
// Check whether the file has declared it is the default lib,
// and whether the user has specifically chosen to avoid checking it.
let skipCheck = node.hasNoDefaultLib && compilerOptions.noLibCheck;
if (!skipCheck) {
checkSourceFileWorker(node);
}
checkSourceFileWorker(node);
checkTime += new Date().getTime() - start;
}
@@ -11358,6 +11370,10 @@ module ts {
function checkSourceFileWorker(node: SourceFile) {
let links = getNodeLinks(node);
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
return;
}
// Grammar checking
checkGrammarSourceFile(node);
+4
View File
@@ -103,6 +103,10 @@ module ts {
name: "noResolve",
type: "boolean",
},
{
name: "skipDefaultLibCheck",
type: "boolean",
},
{
name: "out",
type: "string",
+36
View File
@@ -15,6 +15,42 @@ module ts {
True = -1
}
export function createFileMap<T>(getCanonicalFileName: (fileName: string) => string): FileMap<T> {
let files: Map<T> = {};
return {
get,
set,
contains,
remove,
forEachValue: forEachValueInMap
}
function set(fileName: string, value: T) {
files[normalizeKey(fileName)] = value;
}
function get(fileName: string) {
return files[normalizeKey(fileName)];
}
function contains(fileName: string) {
return hasProperty(files, normalizeKey(fileName));
}
function remove (fileName: string) {
let key = normalizeKey(fileName);
delete files[key];
}
function forEachValueInMap(f: (value: T) => void) {
forEachValue(files, f);
}
function normalizeKey(key: string) {
return getCanonicalFileName(normalizeSlashes(key));
}
}
export const enum Comparison {
LessThan = -1,
EqualTo = 0,
+23 -7
View File
@@ -1646,6 +1646,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function parenthesizeForAccess(expr: Expression): LeftHandSideExpression {
// When diagnosing whether the expression needs parentheses, the decision should be based
// on the innermost expression in a chain of nested type assertions.
while (expr.kind === SyntaxKind.TypeAssertionExpression) {
expr = (<TypeAssertion>expr).expression;
}
// isLeftHandSideExpression is almost the correct criterion for when it is not necessary
// to parenthesize the expression before a dot. The known exceptions are:
//
@@ -1654,7 +1660,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
// NumberLiteral
// 1.x -> not the same as (1).x
//
if (isLeftHandSideExpression(expr) && expr.kind !== SyntaxKind.NewExpression && expr.kind !== SyntaxKind.NumericLiteral) {
if (isLeftHandSideExpression(expr) &&
expr.kind !== SyntaxKind.NewExpression &&
expr.kind !== SyntaxKind.NumericLiteral) {
return <LeftHandSideExpression>expr;
}
let node = <ParenthesizedExpression>createSynthesizedNode(SyntaxKind.ParenthesizedExpression);
@@ -1941,7 +1950,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function emitParenExpression(node: ParenthesizedExpression) {
if (!node.parent || node.parent.kind !== SyntaxKind.ArrowFunction) {
// If the node is synthesized, it means the emitter put the parentheses there,
// not the user. If we didn't want them, the emitter would not have put them
// there.
if (!nodeIsSynthesized(node) && node.parent.kind !== SyntaxKind.ArrowFunction) {
if (node.expression.kind === SyntaxKind.TypeAssertionExpression) {
let operand = (<TypeAssertion>node.expression).expression;
@@ -4491,7 +4503,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emitDeclarationName(node);
write(`", `);
emitDeclarationName(node);
write(")");
write(");");
}
emitExportMemberAssignments(node.name);
}
@@ -4612,7 +4624,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emitDeclarationName(node);
write(`", `);
emitDeclarationName(node);
write(")");
write(");");
}
emitExportMemberAssignments(<Identifier>node.name);
}
@@ -5527,7 +5539,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
Debug.assert(!exportFunctionForFile);
// make sure that name of 'exports' function does not conflict with existing identifiers
exportFunctionForFile = makeUniqueName("exports");
write("System.register([");
write("System.register(");
if (node.moduleName) {
write(`"${node.moduleName}", `);
}
write("[")
for (let i = 0; i < externalImports.length; ++i) {
let text = getExternalModuleNameText(externalImports[i]);
if (i !== 0) {
@@ -5613,8 +5629,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
writeLine();
write("define(");
if (node.amdModuleName) {
write("\"" + node.amdModuleName + "\", ");
if (node.moduleName) {
write("\"" + node.moduleName + "\", ");
}
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true);
write(") {");
+47 -14
View File
@@ -1816,7 +1816,7 @@ module ts {
if (matchesPattern) {
// Report that we need an identifier. However, report it right after the dot,
// and not on the next token. This is because the next token might actually
// be an identifier and the error woudl be quite confusing.
// be an identifier and the error would be quite confusing.
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentToken*/ true, Diagnostics.Identifier_expected);
}
}
@@ -2686,7 +2686,7 @@ module ts {
function nextTokenIsIdentifierOnSameLine() {
nextToken();
return !scanner.hasPrecedingLineBreak() && isIdentifier()
return !scanner.hasPrecedingLineBreak() && isIdentifier();
}
function parseYieldExpression(): YieldExpression {
@@ -3809,14 +3809,42 @@ module ts {
case SyntaxKind.ClassKeyword:
case SyntaxKind.EnumKeyword:
return StatementFlags.Statement;
// 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
// however, an identifier cannot be followed by another identifier on the same line. This is what we
// count on to parse out the respective declarations. For instance, we exploit this to say that
//
// namespace n
//
// can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
//
// namespace
// n
//
// as the identifier 'namespace' on one line followed by the identifier 'n' on another.
// We need to look one token ahead to see if it permissible to try parsing a declaration.
//
// *Note*: 'interface' is actually a strict mode reserved word. So while
//
// "use strict"
// interface
// I {}
//
// could be legal, it would add complexity for very little gain.
case SyntaxKind.InterfaceKeyword:
case SyntaxKind.TypeKeyword:
nextToken();
return isIdentifierOrKeyword() ? StatementFlags.Statement : StatementFlags.None;
return nextTokenIsIdentifierOnSameLine() ? StatementFlags.Statement : StatementFlags.None;
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
return nextTokenIsIdentifierOrStringLiteralOnSameLine() ? StatementFlags.ModuleElement : StatementFlags.None;
case SyntaxKind.DeclareKeyword:
nextToken();
return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral ? StatementFlags.ModuleElement : StatementFlags.None;
// ASI takes effect for this modifier.
if (scanner.hasPrecedingLineBreak()) {
return StatementFlags.None;
}
continue;
case SyntaxKind.ImportKeyword:
nextToken();
return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
@@ -3829,7 +3857,6 @@ module ts {
return StatementFlags.ModuleElement;
}
continue;
case SyntaxKind.DeclareKeyword:
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
@@ -3971,7 +3998,7 @@ module ts {
case SyntaxKind.ThrowKeyword:
return parseThrowStatement();
case SyntaxKind.TryKeyword:
// Include the next two for error recovery.
// Include 'catch' and 'finally' for error recovery.
case SyntaxKind.CatchKeyword:
case SyntaxKind.FinallyKeyword:
return parseTryStatement();
@@ -3979,19 +4006,20 @@ module ts {
return parseDebuggerStatement();
case SyntaxKind.AtToken:
return parseDeclaration();
case SyntaxKind.ConstKeyword:
case SyntaxKind.InterfaceKeyword:
case SyntaxKind.TypeKeyword:
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.ConstKeyword:
case SyntaxKind.EnumKeyword:
case SyntaxKind.ExportKeyword:
case SyntaxKind.ImportKeyword:
case SyntaxKind.InterfaceKeyword:
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.PublicKeyword:
case SyntaxKind.StaticKeyword:
case SyntaxKind.TypeKeyword:
if (getDeclarationFlags() & flags) {
return parseDeclaration();
}
@@ -4042,6 +4070,11 @@ module ts {
}
}
function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
nextToken();
return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral);
}
function parseFunctionBlockOrSemicolon(isGenerator: boolean, diagnosticMessage?: DiagnosticMessage): Block {
if (token !== SyntaxKind.OpenBraceToken && canParseSemicolon()) {
parseSemicolon();
@@ -4583,7 +4616,7 @@ module ts {
function parseModuleBlock(): ModuleBlock {
let node = <ModuleBlock>createNode(SyntaxKind.ModuleBlock, scanner.getStartPos());
if (parseExpected(SyntaxKind.OpenBraceToken)) {
node.statements = parseList(ParsingContext.ModuleElements, /*checkForStrictMode*/false, parseModuleElement);
node.statements = parseList(ParsingContext.ModuleElements, /*checkForStrictMode*/ false, parseModuleElement);
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
@@ -4895,7 +4928,7 @@ module ts {
sourceFile.referencedFiles = referencedFiles;
sourceFile.amdDependencies = amdDependencies;
sourceFile.amdModuleName = amdModuleName;
sourceFile.moduleName = amdModuleName;
}
function setExternalModuleIndicator(sourceFile: SourceFile) {
+23 -19
View File
@@ -10,9 +10,6 @@ module ts {
/** The version of the TypeScript compiler release */
export const version = "1.5.3";
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export function findConfigFile(searchPath: string): string {
var fileName = "tsconfig.json";
while (true) {
@@ -94,10 +91,7 @@ module ts {
}
}
let newLine =
options.newLine === NewLineKind.CarriageReturnLineFeed ? carriageReturnLineFeed :
options.newLine === NewLineKind.LineFeed ? lineFeed :
sys.newLine;
const newLine = getNewLineCharacter(options);
return {
getSourceFile,
@@ -149,13 +143,14 @@ module ts {
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost): Program {
let program: Program;
let files: SourceFile[] = [];
let filesByName: Map<SourceFile> = {};
let filesByName = createFileMap<SourceFile>(fileName => host.getCanonicalFileName(fileName));
let diagnostics = createDiagnosticCollection();
let commonSourceDirectory: string;
let diagnosticsProducingTypeChecker: TypeChecker;
let noDiagnosticsTypeChecker: TypeChecker;
let encounteredTheNoDefaultLibTag = false;
let skipDefaultLib = options.noLib;
let start = new Date().getTime();
@@ -167,8 +162,9 @@ module ts {
// - The '--noLib' flag is used.
// - A 'no-default-lib' reference comment is encountered in
// processing the root files.
if (!(options.noLib || encounteredTheNoDefaultLibTag)) {
processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib*/ true);
forEach(rootNames, name => processRootFile(name, /*isDefaultLib:*/ false));
if (!skipDefaultLib) {
processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib:*/ true);
}
verifyCompilerOptions();
@@ -183,6 +179,7 @@ module ts {
getGlobalDiagnostics,
getSemanticDiagnostics,
getDeclarationDiagnostics,
getCompilerOptionsDiagnostics,
getTypeChecker,
getDiagnosticsProducingTypeChecker,
getCommonSourceDirectory: () => commonSourceDirectory,
@@ -246,8 +243,7 @@ module ts {
}
function getSourceFile(fileName: string) {
fileName = host.getCanonicalFileName(normalizeSlashes(fileName));
return hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined;
return filesByName.get(fileName);
}
function getDiagnosticsHelper(sourceFile: SourceFile, getDiagnostics: (sourceFile: SourceFile) => Diagnostic[]): Diagnostic[] {
@@ -299,6 +295,12 @@ module ts {
}
}
function getCompilerOptionsDiagnostics(): Diagnostic[] {
let allDiagnostics: Diagnostic[] = [];
addRange(allDiagnostics, diagnostics.getGlobalDiagnostics());
return sortAndDeduplicateDiagnostics(allDiagnostics);
}
function getGlobalDiagnostics(): Diagnostic[] {
let typeChecker = getDiagnosticsProducingTypeChecker();
@@ -366,19 +368,19 @@ module ts {
// Get source file from normalized fileName
function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile {
let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName));
if (hasProperty(filesByName, canonicalName)) {
if (filesByName.contains(canonicalName)) {
// We've already looked for this file, use cached result
return getSourceFileFromCache(fileName, canonicalName, /*useAbsolutePath*/ false);
}
else {
let normalizedAbsolutePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
let canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
if (hasProperty(filesByName, canonicalAbsolutePath)) {
if (filesByName.contains(canonicalAbsolutePath)) {
return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true);
}
// We haven't looked for this file, do so now and cache result
let file = filesByName[canonicalName] = host.getSourceFile(fileName, options.target, hostErrorMessage => {
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
if (refFile) {
diagnostics.add(createFileDiagnostic(refFile, refStart, refLength,
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
@@ -387,11 +389,12 @@ module ts {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
});
filesByName.set(canonicalName, file);
if (file) {
encounteredTheNoDefaultLibTag = encounteredTheNoDefaultLibTag || file.hasNoDefaultLib;
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
// Set the source file for normalized absolute path
filesByName[canonicalAbsolutePath] = file;
filesByName.set(canonicalAbsolutePath, file);
if (!options.noResolve) {
let basePath = getDirectoryPath(fileName);
@@ -399,6 +402,7 @@ module ts {
processImportedModules(file, basePath);
}
if (isDefaultLib) {
file.isDefaultLib = true;
files.unshift(file);
}
else {
@@ -410,7 +414,7 @@ module ts {
}
function getSourceFileFromCache(fileName: string, canonicalName: string, useAbsolutePath: boolean): SourceFile {
let file = filesByName[canonicalName];
let file = filesByName.get(canonicalName);
if (file && host.useCaseSensitiveFileNames()) {
let sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName;
if (canonicalName !== sourceFileName) {
+16 -6
View File
@@ -3,6 +3,14 @@ module ts {
[index: string]: T;
}
export interface FileMap<T> {
get(fileName: string): T;
set(fileName: string, value: T): void;
contains(fileName: string): boolean;
remove(fileName: string): void;
forEachValue(f: (v: T) => void): void;
}
export interface TextRange {
pos: number;
end: number;
@@ -1134,7 +1142,7 @@ module ts {
text: string;
amdDependencies: {path: string; name: string}[];
amdModuleName: string;
moduleName: string;
referencedFiles: FileReference[];
/**
@@ -1151,7 +1159,8 @@ module ts {
// The first node that causes this file to be an external module
/* @internal */ externalModuleIndicator: Node;
/* @internal */ isDefaultLib: boolean;
/* @internal */ identifiers: Map<string>;
/* @internal */ nodeCount: number;
/* @internal */ identifierCount: number;
@@ -1205,6 +1214,7 @@ module ts {
getGlobalDiagnostics(): Diagnostic[];
getSemanticDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getDeclarationDiagnostics(sourceFile?: SourceFile): Diagnostic[];
/* @internal */ getCompilerOptionsDiagnostics(): Diagnostic[];
/**
* Gets a type checker that can be used to semantically analyze source fils in the program.
@@ -1830,11 +1840,11 @@ module ts {
isolatedModules?: boolean;
experimentalDecorators?: boolean;
emitDecoratorMetadata?: boolean;
/* @internal */ stripInternal?: boolean;
// Skip checking lib.d.ts to help speed up tests.
/* @internal */ noLibCheck?: boolean;
/* @internal */ stripInternal?: boolean;
// Skip checking lib.d.ts to help speed up tests.
/* @internal */ skipDefaultLibCheck?: boolean;
[option: string]: string | number | boolean;
}
+15
View File
@@ -1985,6 +1985,21 @@ module ts {
return result;
}
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export function getNewLineCharacter(options: CompilerOptions): string {
if (options.newLine === NewLineKind.CarriageReturnLineFeed) {
return carriageReturnLineFeed;
}
else if (options.newLine === NewLineKind.LineFeed) {
return lineFeed;
}
else if (sys) {
return sys.newLine
}
return carriageReturnLineFeed;
}
}
module ts {
+25 -12
View File
@@ -809,9 +809,14 @@ module Harness {
}
}
export function createSourceFileAndAssertInvariants(fileName: string, sourceText: string, languageVersion: ts.ScriptTarget, assertInvariants: boolean) {
export function createSourceFileAndAssertInvariants(
fileName: string,
sourceText: string,
languageVersion: ts.ScriptTarget,
assertInvariants: boolean) {
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ assertInvariants);
if (assertInvariants) {
Utils.assertInvariants(result, /*parent:*/ undefined);
}
@@ -834,13 +839,14 @@ module Harness {
return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
}
export function createCompilerHost(inputFiles: { unitName: string; content: string; }[],
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
scriptTarget: ts.ScriptTarget,
useCaseSensitiveFileNames: boolean,
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
currentDirectory?: string,
newLineKind?: ts.NewLineKind): ts.CompilerHost {
export function createCompilerHost(
inputFiles: { unitName: string; content: string; }[],
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
scriptTarget: ts.ScriptTarget,
useCaseSensitiveFileNames: boolean,
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
currentDirectory?: string,
newLineKind?: ts.NewLineKind): ts.CompilerHost {
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
function getCanonicalFileName(fileName: string): string {
@@ -962,14 +968,15 @@ module Harness {
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
options.noErrorTruncation = true;
if (lightMode) {
options.noLibCheck = true;
options.skipDefaultLibCheck = true;
}
if (settingsCallback) {
settingsCallback(null);
}
var newLine = '\r\n';
let newLine = '\r\n';
options.skipDefaultLibCheck = true;
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
// Treat them as library files, so include them in build, but not in baselines.
@@ -986,9 +993,11 @@ module Harness {
// always push the default lib in *last* to normalize the type/symbol baselines.
programFiles.push(defaultLibFileName);
}
var program = ts.createProgram(programFiles, options, createCompilerHost(inputFiles.concat(includeBuiltFiles).concat(otherFiles),
var compilerHost = createCompilerHost(inputFiles.concat(includeBuiltFiles).concat(otherFiles),
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine));
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
var program = ts.createProgram(programFiles, options, compilerHost);
var emitResult = program.emit();
@@ -1081,6 +1090,10 @@ module Harness {
options.outDir = setting.value;
break;
case 'skipdefaultlibcheck':
options.skipDefaultLibCheck = setting.value === "true";
break;
case 'sourceroot':
options.sourceRoot = setting.value;
break;
+14 -7
View File
@@ -7677,10 +7677,10 @@ declare var MediaQueryList: {
interface MediaSource extends EventTarget {
activeSourceBuffers: SourceBufferList;
duration: number;
readyState: string;
readyState: number;
sourceBuffers: SourceBufferList;
addSourceBuffer(type: string): SourceBuffer;
endOfStream(error?: string): void;
endOfStream(error?: number): void;
removeSourceBuffer(sourceBuffer: SourceBuffer): void;
}
@@ -8409,7 +8409,7 @@ declare var PopStateEvent: {
interface Position {
coords: Coordinates;
timestamp: Date;
timestamp: number;
}
declare var Position: {
@@ -11090,9 +11090,17 @@ interface WebGLRenderingContext {
stencilMaskSeparate(face: number, mask: number): void;
stencilOp(fail: number, zfail: number, zpass: number): void;
stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void;
texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, image: HTMLImageElement): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, canvas: HTMLCanvasElement): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, video: HTMLVideoElement): void;
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageData): void;
texParameterf(target: number, pname: number, param: number): void;
texParameteri(target: number, pname: number, param: number): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, image: HTMLImageElement): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, canvas: HTMLCanvasElement): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, video: HTMLVideoElement): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageData): void;
uniform1f(location: WebGLUniformLocation, x: number): void;
uniform1fv(location: WebGLUniformLocation, v: any): void;
@@ -12332,10 +12340,11 @@ interface DocumentEvent {
createEvent(eventInterface:"AriaRequestEvent"): AriaRequestEvent;
createEvent(eventInterface:"AudioProcessingEvent"): AudioProcessingEvent;
createEvent(eventInterface:"BeforeUnloadEvent"): BeforeUnloadEvent;
createEvent(eventInterface:"ClipboardEvent"): ClipboardEvent;
createEvent(eventInterface:"CloseEvent"): CloseEvent;
createEvent(eventInterface:"CommandEvent"): CommandEvent;
createEvent(eventInterface:"CompositionEvent"): CompositionEvent;
createEvent(eventInterface: "CustomEvent"): CustomEvent;
createEvent(eventInterface:"CustomEvent"): CustomEvent;
createEvent(eventInterface:"DeviceMotionEvent"): DeviceMotionEvent;
createEvent(eventInterface:"DeviceOrientationEvent"): DeviceOrientationEvent;
createEvent(eventInterface:"DragEvent"): DragEvent;
@@ -12358,8 +12367,6 @@ interface DocumentEvent {
createEvent(eventInterface:"MouseEvent"): MouseEvent;
createEvent(eventInterface:"MouseEvents"): MouseEvent;
createEvent(eventInterface:"MouseWheelEvent"): MouseWheelEvent;
createEvent(eventInterface:"MSGestureEvent"): MSGestureEvent;
createEvent(eventInterface:"MSPointerEvent"): MSPointerEvent;
createEvent(eventInterface:"MutationEvent"): MutationEvent;
createEvent(eventInterface:"MutationEvents"): MutationEvent;
createEvent(eventInterface:"NavigationCompletedEvent"): NavigationCompletedEvent;
@@ -12971,4 +12978,4 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any,
declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void;
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
+52 -32
View File
@@ -735,7 +735,7 @@ module ts {
public endOfFileToken: Node;
public amdDependencies: { name: string; path: string }[];
public amdModuleName: string;
public moduleName: string;
public referencedFiles: FileReference[];
public syntacticDiagnostics: Diagnostic[];
@@ -743,6 +743,7 @@ module ts {
public parseDiagnostics: Diagnostic[];
public bindDiagnostics: Diagnostic[];
public isDefaultLib: boolean;
public hasNoDefaultLib: boolean;
public externalModuleIndicator: Node; // The first node that causes this file to be an external module
public nodeCount: number;
@@ -960,6 +961,7 @@ module ts {
log? (s: string): void;
trace? (s: string): void;
error? (s: string): void;
useCaseSensitiveFileNames? (): boolean;
}
//
@@ -1632,12 +1634,12 @@ module ts {
// at each language service public entry point, since we don't know when
// set of scripts handled by the host changes.
class HostCache {
private fileNameToEntry: Map<HostFileInformation>;
private fileNameToEntry: FileMap<HostFileInformation>;
private _compilationSettings: CompilerOptions;
constructor(private host: LanguageServiceHost, private getCanonicalFileName: (fileName: string) => string) {
constructor(private host: LanguageServiceHost, getCanonicalFileName: (fileName: string) => string) {
// script id => script index
this.fileNameToEntry = {};
this.fileNameToEntry = createFileMap<HostFileInformation>(getCanonicalFileName);
// Initialize the list with the root file names
let rootFileNames = host.getScriptFileNames();
@@ -1653,10 +1655,6 @@ module ts {
return this._compilationSettings;
}
private normalizeFileName(fileName: string): string {
return this.getCanonicalFileName(normalizeSlashes(fileName));
}
private createEntry(fileName: string) {
let entry: HostFileInformation;
let scriptSnapshot = this.host.getScriptSnapshot(fileName);
@@ -1668,15 +1666,16 @@ module ts {
};
}
return this.fileNameToEntry[this.normalizeFileName(fileName)] = entry;
this.fileNameToEntry.set(fileName, entry);
return entry;
}
private getEntry(fileName: string): HostFileInformation {
return lookUp(this.fileNameToEntry, this.normalizeFileName(fileName));
return this.fileNameToEntry.get(fileName);
}
private contains(fileName: string): boolean {
return hasProperty(this.fileNameToEntry, this.normalizeFileName(fileName));
return this.fileNameToEntry.contains(fileName);
}
public getOrCreateEntry(fileName: string): HostFileInformation {
@@ -1690,10 +1689,9 @@ module ts {
public getRootFileNames(): string[] {
let fileNames: string[] = [];
forEachKey(this.fileNameToEntry, key => {
let entry = this.getEntry(key);
if (entry) {
fileNames.push(entry.hostFileName);
this.fileNameToEntry.forEachValue(value => {
if (value) {
fileNames.push(value.hostFileName);
}
});
@@ -1765,8 +1763,10 @@ module ts {
* Extra compiler options that will unconditionally be used bu this function are:
* - isolatedModules = true
* - allowNonTsExtensions = true
* - noLib = true
* - noResolve = true
*/
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[]): string {
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions();
options.isolatedModules = true;
@@ -1774,15 +1774,28 @@ module ts {
// Filename can be non-ts file.
options.allowNonTsExtensions = true;
// We are not returning a sourceFile for lib file when asked by the program,
// so pass --noLib to avoid reporting a file not found error.
options.noLib = true;
// We are not doing a full typecheck, we are not resolving the whole context,
// so pass --noResolve to avoid reporting missing file errors.
options.noResolve = true;
// Parse
var inputFileName = fileName || "module.ts";
var sourceFile = createSourceFile(inputFileName, input, options.target);
let inputFileName = fileName || "module.ts";
let sourceFile = createSourceFile(inputFileName, input, options.target);
if (moduleName) {
sourceFile.moduleName = moduleName;
}
// Store syntactic diagnostics
if (diagnostics && sourceFile.parseDiagnostics) {
diagnostics.push(...sourceFile.parseDiagnostics);
}
let newLine = getNewLineCharacter(options);
// Output
let outputText: string;
@@ -1797,13 +1810,13 @@ module ts {
useCaseSensitiveFileNames: () => false,
getCanonicalFileName: fileName => fileName,
getCurrentDirectory: () => "",
getNewLine: () => (sys && sys.newLine) || "\r\n"
getNewLine: () => newLine
};
var program = createProgram([inputFileName], options, compilerHost);
if (diagnostics) {
diagnostics.push(...program.getGlobalDiagnostics());
diagnostics.push(...program.getCompilerOptionsDiagnostics());
}
// Emit
@@ -1873,20 +1886,28 @@ module ts {
return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true);
}
export function createDocumentRegistry(): DocumentRegistry {
function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
return useCaseSensitivefileNames
? ((fileName) => fileName)
: ((fileName) => fileName.toLowerCase());
}
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean): DocumentRegistry {
// Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
// for those settings.
let buckets: Map<Map<DocumentRegistryEntry>> = {};
let buckets: Map<FileMap<DocumentRegistryEntry>> = {};
let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames);
function getKeyFromCompilationSettings(settings: CompilerOptions): string {
return "_" + settings.target; // + "|" + settings.propagateEnumConstantoString()
}
function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): Map<DocumentRegistryEntry> {
function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap<DocumentRegistryEntry> {
let key = getKeyFromCompilationSettings(settings);
let bucket = lookUp(buckets, key);
if (!bucket && createIfMissing) {
buckets[key] = bucket = {};
buckets[key] = bucket = createFileMap<DocumentRegistryEntry>(getCanonicalFileName);
}
return bucket;
}
@@ -1896,7 +1917,7 @@ module ts {
let entries = lookUp(buckets, name);
let sourceFiles: { name: string; refCount: number; references: string[]; }[] = [];
for (let i in entries) {
let entry = entries[i];
let entry = entries.get(i);
sourceFiles.push({
name: i,
refCount: entry.languageServiceRefCount,
@@ -1928,18 +1949,19 @@ module ts {
acquiring: boolean): SourceFile {
let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true);
let entry = lookUp(bucket, fileName);
let entry = bucket.get(fileName);
if (!entry) {
Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
// Have never seen this file with these settings. Create a new source file for it.
let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false);
bucket[fileName] = entry = {
entry = {
sourceFile: sourceFile,
languageServiceRefCount: 0,
owners: []
};
bucket.set(fileName, entry);
}
else {
// We have an entry for this file. However, it may be for a different version of
@@ -1967,12 +1989,12 @@ module ts {
let bucket = getBucketForCompilationSettings(compilationSettings, false);
Debug.assert(bucket !== undefined);
let entry = lookUp(bucket, fileName);
let entry = bucket.get(fileName);
entry.languageServiceRefCount--;
Debug.assert(entry.languageServiceRefCount >= 0);
if (entry.languageServiceRefCount === 0) {
delete bucket[fileName];
bucket.remove(fileName);
}
}
@@ -2400,9 +2422,7 @@ module ts {
}
}
function getCanonicalFileName(fileName: string) {
return useCaseSensitivefileNames ? fileName : fileName.toLowerCase();
}
let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames);
function getValidSourceFile(fileName: string): SourceFile {
fileName = normalizeSlashes(fileName);
+9 -1
View File
@@ -56,6 +56,7 @@ module ts {
getDefaultLibFileName(options: string): string;
getNewLine?(): string;
getProjectVersion?(): string;
useCaseSensitiveFileNames?(): boolean;
}
/** Public interface of the the of a config service shim instance.*/
@@ -270,6 +271,10 @@ module ts {
return this.shimHost.getProjectVersion();
}
public useCaseSensitiveFileNames(): boolean {
return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
}
public getCompilationSettings(): CompilerOptions {
var settingsJson = this.shimHost.getCompilationSettings();
if (settingsJson == null || settingsJson == "") {
@@ -909,7 +914,7 @@ module ts {
export class TypeScriptServicesFactory implements ShimFactory {
private _shims: Shim[] = [];
private documentRegistry: DocumentRegistry = createDocumentRegistry();
private documentRegistry: DocumentRegistry;
/*
* Returns script API version.
@@ -920,6 +925,9 @@ module ts {
public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim {
try {
if (this.documentRegistry === undefined) {
this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
}
var hostAdapter = new LanguageServiceShimHostAdapter(host);
var languageService = createLanguageService(hostAdapter, this.documentRegistry);
return new LanguageServiceShimObject(this, host, languageService);