merge with master

This commit is contained in:
Vladimir Matveev
2015-10-11 12:42:27 -07:00
586 changed files with 6942 additions and 2978 deletions
+9 -1
View File
@@ -207,8 +207,9 @@ namespace ts {
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
Debug.assert(!hasDynamicName(node));
let isDefaultExport = node.flags & NodeFlags.Default;
// The exported symbol for an export default function/class node is always named "default"
let name = node.flags & NodeFlags.Default && parent ? "default" : getDeclarationName(node);
let name = isDefaultExport && parent ? "default" : getDeclarationName(node);
let symbol: Symbol;
if (name !== undefined) {
@@ -249,6 +250,13 @@ namespace ts {
let message = symbol.flags & SymbolFlags.BlockScopedVariable
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
: Diagnostics.Duplicate_identifier_0;
forEach(symbol.declarations, declaration => {
if (declaration.flags & NodeFlags.Default) {
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
}
});
forEach(symbol.declarations, declaration => {
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
});
+105 -85
View File
@@ -2211,7 +2211,7 @@ namespace ts {
/**
* Push an entry on the type resolution stack. If an entry with the given target and the given property name
* is already on the stack, and no entries in between already have a type, then a circularity has occurred.
* is already on the stack, and no entries in between already have a type, then a circularity has occurred.
* In this case, the result values of the existing entry and all entries pushed after it are changed to false,
* and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
* In order to see if the same query has already been done before, the target object and the propertyName both
@@ -3173,8 +3173,8 @@ namespace ts {
members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
callSignatures = instantiateList(source.declaredCallSignatures, mapper, instantiateSignature);
constructSignatures = instantiateList(source.declaredConstructSignatures, mapper, instantiateSignature);
stringIndexType = source.declaredStringIndexType ? instantiateType(source.declaredStringIndexType, mapper) : undefined;
numberIndexType = source.declaredNumberIndexType ? instantiateType(source.declaredNumberIndexType, mapper) : undefined;
stringIndexType = instantiateType(source.declaredStringIndexType, mapper);
numberIndexType = instantiateType(source.declaredNumberIndexType, mapper);
}
let baseTypes = getBaseTypes(source);
if (baseTypes.length) {
@@ -3373,7 +3373,7 @@ namespace ts {
setObjectTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexType, numberIndexType);
}
function resolveAnonymousTypeMembers(type: ObjectType) {
function resolveAnonymousTypeMembers(type: AnonymousType) {
let symbol = type.symbol;
let members: SymbolTable;
let callSignatures: Signature[];
@@ -3381,7 +3381,14 @@ namespace ts {
let stringIndexType: Type;
let numberIndexType: Type;
if (symbol.flags & SymbolFlags.TypeLiteral) {
if (type.target) {
members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
callSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper, instantiateSignature);
constructSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper, instantiateSignature);
stringIndexType = instantiateType(getIndexTypeOfType(type.target, IndexKind.String), type.mapper);
numberIndexType = instantiateType(getIndexTypeOfType(type.target, IndexKind.Number), type.mapper);
}
else if (symbol.flags & SymbolFlags.TypeLiteral) {
members = symbol.members;
callSignatures = getSignaturesOfSymbol(members["__call"]);
constructSignatures = getSignaturesOfSymbol(members["__new"]);
@@ -3426,7 +3433,7 @@ namespace ts {
resolveClassOrInterfaceMembers(<InterfaceType>type);
}
else if (type.flags & TypeFlags.Anonymous) {
resolveAnonymousTypeMembers(<ObjectType>type);
resolveAnonymousTypeMembers(<AnonymousType>type);
}
else if (type.flags & TypeFlags.Tuple) {
resolveTupleTypeMembers(<TupleType>type);
@@ -4545,7 +4552,7 @@ namespace ts {
}
let result = createSignature(signature.declaration, freshTypeParameters,
instantiateList(signature.parameters, mapper, instantiateSymbol),
signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined,
instantiateType(signature.resolvedReturnType, mapper),
freshTypePredicate,
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
result.target = signature;
@@ -4577,7 +4584,7 @@ namespace ts {
return result;
}
function instantiateAnonymousType(type: ObjectType, mapper: TypeMapper): ObjectType {
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): ObjectType {
if (mapper.instantiations) {
let cachedType = mapper.instantiations[type.id];
if (cachedType) {
@@ -4588,27 +4595,21 @@ namespace ts {
mapper.instantiations = [];
}
// Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it
let result = <ResolvedType>createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol);
result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol);
result.members = createSymbolTable(result.properties);
result.callSignatures = instantiateList(getSignaturesOfType(type, SignatureKind.Call), mapper, instantiateSignature);
result.constructSignatures = instantiateList(getSignaturesOfType(type, SignatureKind.Construct), mapper, instantiateSignature);
let stringIndexType = getIndexTypeOfType(type, IndexKind.String);
let numberIndexType = getIndexTypeOfType(type, IndexKind.Number);
if (stringIndexType) result.stringIndexType = instantiateType(stringIndexType, mapper);
if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper);
let result = <AnonymousType>createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol);
result.target = type;
result.mapper = mapper;
mapper.instantiations[type.id] = result;
return result;
}
function instantiateType(type: Type, mapper: TypeMapper): Type {
if (mapper !== identityMapper) {
if (type && mapper !== identityMapper) {
if (type.flags & TypeFlags.TypeParameter) {
return mapper(<TypeParameter>type);
}
if (type.flags & TypeFlags.Anonymous) {
return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) ?
instantiateAnonymousType(<ObjectType>type, mapper) : type;
instantiateAnonymousType(<AnonymousType>type, mapper) : type;
}
if (type.flags & TypeFlags.Reference) {
return createTypeReference((<TypeReference>type).target, instantiateList((<TypeReference>type).typeArguments, mapper, instantiateType));
@@ -5244,7 +5245,7 @@ namespace ts {
// Only want to compare the construct signatures for abstractness guarantees.
// Because the "abstractness" of a class is the same across all construct signatures
// (internally we are checking the corresponding declaration), it is enough to perform
// (internally we are checking the corresponding declaration), it is enough to perform
// the check and report an error once over all pairs of source and target construct signatures.
//
// sourceSig and targetSig are (possibly) undefined.
@@ -6643,7 +6644,7 @@ namespace ts {
let needToCaptureLexicalThis = false;
if (!isCallExpression) {
// adjust the container reference in case if super is used inside arrow functions with arbitrary deep nesting
// adjust the container reference in case if super is used inside arrow functions with arbitrary deep nesting
while (container && container.kind === SyntaxKind.ArrowFunction) {
container = getSuperContainer(container, /*includeFunctions*/ true);
needToCaptureLexicalThis = languageVersion < ScriptTarget.ES6;
@@ -6653,7 +6654,7 @@ namespace ts {
let canUseSuperExpression = isLegalUsageOfSuperExpression(container);
let nodeCheckFlag: NodeCheckFlags = 0;
// always set NodeCheckFlags for 'super' expression node
// always set NodeCheckFlags for 'super' expression node
if (canUseSuperExpression) {
if ((container.flags & NodeFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
@@ -7314,15 +7315,15 @@ namespace ts {
}
function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type {
let inDestructuringPattern = isAssignmentTarget(node);
// Grammar checking
checkGrammarObjectLiteralExpression(node);
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
let propertiesTable: SymbolTable = {};
let propertiesArray: Symbol[] = [];
let contextualType = getContextualType(node);
let contextualTypeHasPattern = contextualType && contextualType.pattern &&
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
let inDestructuringPattern = isAssignmentTarget(node);
let typeFlags: TypeFlags = 0;
for (let memberDecl of node.properties) {
@@ -7346,7 +7347,10 @@ namespace ts {
if (inDestructuringPattern) {
// If object literal is an assignment pattern and if the assignment pattern specifies a default value
// for the property, make the property optional.
if (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) {
const isOptional =
(memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) ||
(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (<ShorthandPropertyAssignment>memberDecl).objectAssignmentInitializer);
if (isOptional) {
prop.flags |= SymbolFlags.Optional;
}
}
@@ -7633,7 +7637,9 @@ namespace ts {
// Look up the value in the current scope
if (valueSymbol && valueSymbol !== unknownSymbol) {
links.jsxFlags |= JsxFlags.ClassElement;
getSymbolLinks(valueSymbol).referenced = true;
if (valueSymbol.flags & SymbolFlags.Alias) {
markAliasSymbolAsReferenced(valueSymbol);
}
}
return valueSymbol || unknownSymbol;
@@ -8123,6 +8129,7 @@ namespace ts {
/**
* If indexArgumentExpression is a string literal or number literal, returns its text.
* If indexArgumentExpression is a constant value, returns its string value.
* 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.
@@ -8131,6 +8138,12 @@ namespace ts {
if (indexArgumentExpression.kind === SyntaxKind.StringLiteral || indexArgumentExpression.kind === SyntaxKind.NumericLiteral) {
return (<LiteralExpression>indexArgumentExpression).text;
}
if (indexArgumentExpression.kind === SyntaxKind.ElementAccessExpression || indexArgumentExpression.kind === SyntaxKind.PropertyAccessExpression) {
let value = getConstantValue(<ElementAccessExpression | PropertyAccessExpression>indexArgumentExpression);
if (value !== undefined) {
return value.toString();
}
}
if (checkThatExpressionIsProperSymbolReference(indexArgumentExpression, indexArgumentType, /*reportError*/ false)) {
let rightHandSideName = (<Identifier>(<PropertyAccessExpression>indexArgumentExpression).name).text;
return getPropertyNameForKnownSymbolName(rightHandSideName);
@@ -8566,7 +8579,7 @@ namespace ts {
// A method or accessor declaration decorator will have two or three arguments (see
// `PropertyDecorator` and `MethodDecorator` in core.d.ts)
// If we are emitting decorators for ES3, we will only pass two arguments.
// If we are emitting decorators for ES3, we will only pass two arguments.
if (languageVersion === ScriptTarget.ES3) {
return 2;
}
@@ -9726,7 +9739,7 @@ namespace ts {
return !symbol || symbol === unknownSymbol || (symbol.flags & ~SymbolFlags.EnumMember) !== 0;
}
case SyntaxKind.ElementAccessExpression:
// old compiler doesn't check indexed assess
// old compiler doesn't check indexed access
return true;
case SyntaxKind.ParenthesizedExpression:
return isReferenceOrErrorExpression((<ParenthesizedExpression>n).expression);
@@ -9884,32 +9897,32 @@ namespace ts {
return (symbol.flags & SymbolFlags.ConstEnum) !== 0;
}
function checkInstanceOfExpression(node: BinaryExpression, leftType: Type, rightType: Type): Type {
function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
// TypeScript 1.0 spec (April 2014): 4.15.4
// The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
// 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 (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);
error(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 (!(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);
error(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;
}
function checkInExpression(node: BinaryExpression, leftType: Type, rightType: Type): Type {
function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
// TypeScript 1.0 spec (April 2014): 4.15.5
// 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 (!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);
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
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);
error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
return booleanType;
}
@@ -9926,7 +9939,12 @@ namespace ts {
isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
getIndexTypeOfType(sourceType, IndexKind.String);
if (type) {
checkDestructuringAssignment((<PropertyAssignment>p).initializer || name, type);
if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
checkDestructuringAssignment(<ShorthandPropertyAssignment>p, type);
}
else {
checkDestructuringAssignment((<PropertyAssignment>p).initializer || name, type);
}
}
else {
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), declarationNameToString(name));
@@ -9986,7 +10004,19 @@ namespace ts {
return sourceType;
}
function checkDestructuringAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, contextualMapper?: TypeMapper): Type {
let target: Expression;
if (exprOrAssignment.kind === SyntaxKind.ShorthandPropertyAssignment) {
const prop = <ShorthandPropertyAssignment>exprOrAssignment;
if (prop.objectAssignmentInitializer) {
checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, contextualMapper);
}
target = (<ShorthandPropertyAssignment>exprOrAssignment).name;
}
else {
target = <Expression>exprOrAssignment;
}
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
checkBinaryExpression(<BinaryExpression>target, contextualMapper);
target = (<BinaryExpression>target).left;
@@ -10009,12 +10039,16 @@ namespace ts {
}
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
let operator = node.operatorToken.kind;
if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper);
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
}
function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, contextualMapper?: TypeMapper, errorNode?: Node) {
let operator = operatorToken.kind;
if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) {
return checkDestructuringAssignment(left, checkExpression(right, contextualMapper), contextualMapper);
}
let leftType = checkExpression(node.left, contextualMapper);
let rightType = checkExpression(node.right, contextualMapper);
let leftType = checkExpression(left, contextualMapper);
let rightType = checkExpression(right, contextualMapper);
switch (operator) {
case SyntaxKind.AsteriskToken:
case SyntaxKind.AsteriskEqualsToken:
@@ -10050,13 +10084,13 @@ namespace ts {
// try and return them a helpful suggestion
if ((leftType.flags & TypeFlags.Boolean) &&
(rightType.flags & TypeFlags.Boolean) &&
(suggestedOperator = getSuggestedBooleanOperator(node.operatorToken.kind)) !== undefined) {
error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operatorToken.kind), tokenToString(suggestedOperator));
(suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
error(errorNode || operatorToken, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(operatorToken.kind), tokenToString(suggestedOperator));
}
else {
// otherwise just check each operand separately and report errors as normal
let leftOk = checkArithmeticOperandType(node.left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
let rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
let leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
let rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
if (leftOk && rightOk) {
checkAssignmentOperator(numberType);
}
@@ -10122,9 +10156,9 @@ namespace ts {
}
return booleanType;
case SyntaxKind.InstanceOfKeyword:
return checkInstanceOfExpression(node, leftType, rightType);
return checkInstanceOfExpression(left, right, leftType, rightType);
case SyntaxKind.InKeyword:
return checkInExpression(node, leftType, rightType);
return checkInExpression(left, right, leftType, rightType);
case SyntaxKind.AmpersandAmpersandToken:
return rightType;
case SyntaxKind.BarBarToken:
@@ -10139,8 +10173,8 @@ namespace ts {
// Return true if there was no error, false if there was an error.
function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
let offendingSymbolOperand =
someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? node.left :
someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? node.right :
someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? left :
someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? right :
undefined;
if (offendingSymbolOperand) {
error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(operator));
@@ -10174,17 +10208,17 @@ namespace ts {
// requires VarExpr to be classified as a reference
// A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
// and the type of the non - compound operation to be assignable to the type of VarExpr.
let ok = checkReferenceExpression(node.left, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
let ok = checkReferenceExpression(left, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
// Use default messages
if (ok) {
// to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
checkTypeAssignableTo(valueType, leftType, node.left, /*headMessage*/ undefined);
checkTypeAssignableTo(valueType, leftType, left, /*headMessage*/ undefined);
}
}
}
function reportOperatorError() {
error(node, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType));
error(errorNode || operatorToken, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(operatorToken.kind), typeToString(leftType), typeToString(rightType));
}
}
@@ -11295,7 +11329,8 @@ namespace ts {
}
function checkNonThenableType(type: Type, location?: Node, message?: DiagnosticMessage) {
if (!(type.flags & TypeFlags.Any) && isTypeAssignableTo(type, getGlobalThenableType())) {
type = getWidenedType(type);
if (!isTypeAny(type) && isTypeAssignableTo(type, getGlobalThenableType())) {
if (location) {
if (!message) {
message = Diagnostics.Operand_for_await_does_not_have_a_valid_callable_then_member;
@@ -12533,7 +12568,12 @@ namespace ts {
if (isAsyncFunctionLike(func)) {
let promisedType = getPromisedType(returnType);
let awaitedType = checkAwaitedType(exprType, node.expression, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
checkTypeAssignableTo(awaitedType, promisedType, node.expression);
if (promisedType) {
// If the function has a return type, but promisedType is
// undefined, an error will be reported in checkAsyncFunctionReturnType
// so we don't need to report one here.
checkTypeAssignableTo(awaitedType, promisedType, node.expression);
}
}
else {
checkTypeAssignableTo(exprType, returnType, node.expression);
@@ -13143,13 +13183,13 @@ namespace ts {
autoValue = computeConstantValueForEnumMemberInitializer(initializer, enumType, enumIsConst, ambient);
}
else if (ambient && !enumIsConst) {
// In ambient enum declarations that specify no const modifier, enum member declarations
// In ambient enum declarations that specify no const modifier, enum member declarations
// that omit a value are considered computed members (as opposed to having auto-incremented values assigned).
autoValue = undefined;
}
else if (previousEnumMemberIsNonConstant) {
// If the member declaration specifies no value, the member is considered a constant enum member.
// If the member is the first member in the enum declaration, it is assigned the value zero.
// If the member declaration specifies no value, the member is considered a constant enum member.
// If the member is the first member in the enum declaration, it is assigned the value zero.
// Otherwise, it is assigned the value of the immediately preceding member plus one,
// and an error occurs if the immediately preceding member is not a constant enum member
error(member.name, Diagnostics.Enum_member_must_have_initializer);
@@ -14089,7 +14129,7 @@ namespace ts {
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
// If we didn't come from static member of class or interface,
// add the type parameters into the symbol table
// add the type parameters into the symbol table
// (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
// Note: that the memberFlags come from previous iteration.
if (!(memberFlags & NodeFlags.Static)) {
@@ -14753,31 +14793,6 @@ namespace ts {
return symbol && getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
}
function getBlockScopedVariableId(n: Identifier): number {
Debug.assert(!nodeIsSynthesized(n));
let isVariableDeclarationOrBindingElement =
n.parent.kind === SyntaxKind.BindingElement || (n.parent.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>n.parent).name === n);
let symbol =
(isVariableDeclarationOrBindingElement ? getSymbolOfNode(n.parent) : undefined) ||
getNodeLinks(n).resolvedSymbol ||
resolveName(n, n.text, SymbolFlags.Value | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined);
let isLetOrConst =
symbol &&
(symbol.flags & SymbolFlags.BlockScopedVariable) &&
symbol.valueDeclaration.parent.kind !== SyntaxKind.CatchClause;
if (isLetOrConst) {
// side-effect of calling this method:
// assign id to symbol if it was not yet set
getSymbolLinks(symbol);
return symbol.id;
}
return undefined;
}
function instantiateSingleCallFunctionType(functionType: Type, typeArguments: Type[]): Type {
if (functionType === unknownType) {
return unknownType;
@@ -14812,7 +14827,6 @@ namespace ts {
isEntityNameVisible,
getConstantValue,
collectLinkedAliases,
getBlockScopedVariableId,
getReferencedValueDeclaration,
getTypeReferenceSerializationKind,
isOptionalParameter
@@ -15423,7 +15437,7 @@ namespace ts {
}
}
function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression) {
function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) {
let seen: Map<SymbolFlags> = {};
let Property = 1;
let GetAccessor = 2;
@@ -15439,6 +15453,12 @@ namespace ts {
continue;
}
if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && (<ShorthandPropertyAssignment>prop).objectAssignmentInitializer) {
// having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
// outside of destructuring it is a syntax error
return grammarErrorOnNode((<ShorthandPropertyAssignment>prop).equalsToken, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
}
// ECMA-262 11.1.5 Object Initialiser
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
// a.This production is contained in strict code and IsDataDescriptor(previous) is true and
+4 -1
View File
@@ -468,6 +468,9 @@ namespace ts {
}
if (opt.isFilePath) {
value = normalizePath(combinePaths(basePath, value));
if (value === "") {
value = ".";
}
}
options[opt.name] = value;
}
@@ -517,4 +520,4 @@ namespace ts {
return fileNames;
}
}
}
}
+8
View File
@@ -800,6 +800,10 @@
"category": "Error",
"code": 1311
},
"'=' can only be used in an object literal property inside a destructuring assignment.": {
"category": "Error",
"code": 1312
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300
@@ -1656,6 +1660,10 @@
"category": "Error",
"code": 2527
},
"A module cannot have multiple default exports.": {
"category": "Error",
"code": 2528
},
"JSX element attributes type '{0}' must be an object type.": {
"category": "Error",
"code": 2600
+40 -25
View File
@@ -446,7 +446,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
/** If removeComments is true, no leading-comments needed to be emitted **/
let emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos: number) { } : emitLeadingCommentsOfPositionWorker;
let moduleEmitDelegates: Map<(node: SourceFile, startIndex: number) => void> = {
let moduleEmitDelegates: Map<(node: SourceFile) => void> = {
[ModuleKind.ES6]: emitES6Module,
[ModuleKind.AMD]: emitAMDModule,
[ModuleKind.System]: emitSystemModule,
@@ -2311,6 +2311,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(": ");
emit(node.name);
}
if (languageVersion >= ScriptTarget.ES6 && node.objectAssignmentInitializer) {
write(" = ");
emit(node.objectAssignmentInitializer);
}
}
function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean {
@@ -3574,7 +3579,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
for (let p of properties) {
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
let propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
emitDestructuringAssignment((<PropertyAssignment>p).initializer || propName, createPropertyAccessForDestructuringProperty(value, propName));
let target = p.kind === SyntaxKind.ShorthandPropertyAssignment ? <ShorthandPropertyAssignment>p : (<PropertyAssignment>p).initializer || propName;
emitDestructuringAssignment(target, createPropertyAccessForDestructuringProperty(value, propName));
}
}
}
@@ -3599,8 +3605,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}
function emitDestructuringAssignment(target: Expression, value: Expression) {
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
function emitDestructuringAssignment(target: Expression | ShorthandPropertyAssignment, value: Expression) {
if (target.kind === SyntaxKind.ShorthandPropertyAssignment) {
if ((<ShorthandPropertyAssignment>target).objectAssignmentInitializer) {
value = createDefaultValueCheck(value, (<ShorthandPropertyAssignment>target).objectAssignmentInitializer);
}
target = (<ShorthandPropertyAssignment>target).name;
}
else if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
value = createDefaultValueCheck(value, (<BinaryExpression>target).right);
target = (<BinaryExpression>target).left;
}
@@ -3785,7 +3797,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(";");
}
}
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
if (modulekind !== ModuleKind.ES6 && node.parent === currentSourceFile) {
forEach(node.declarationList.declarations, emitExportVariableAssignments);
}
}
@@ -4011,7 +4023,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
emitSignatureAndBody(node);
if (languageVersion < ScriptTarget.ES6 && node.kind === SyntaxKind.FunctionDeclaration && node.parent === currentSourceFile && node.name) {
if (modulekind !== ModuleKind.ES6 && node.kind === SyntaxKind.FunctionDeclaration && node.parent === currentSourceFile && node.name) {
emitExportMemberAssignments((<FunctionDeclaration>node).name);
}
@@ -4687,6 +4699,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
else {
emitClassLikeDeclarationForES6AndHigher(node);
}
if (modulekind !== ModuleKind.ES6 && node.parent === currentSourceFile && node.name) {
emitExportMemberAssignments(node.name);
}
}
function emitClassLikeDeclarationForES6AndHigher(node: ClassLikeDeclaration) {
@@ -4785,8 +4800,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
// emit name if
// - node has a name
// - this is default export and target is not ES6 (for ES6 `export default` does not need to be compiled downlevel)
if ((node.name || (node.flags & NodeFlags.Default && languageVersion < ScriptTarget.ES6)) && !thisNodeIsDecorated) {
// - this is default export with static initializers
if ((node.name || (node.flags & NodeFlags.Default && staticProperties.length > 0)) && !thisNodeIsDecorated) {
write(" ");
emitDeclarationName(node);
}
@@ -4934,10 +4949,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
if (node.kind === SyntaxKind.ClassDeclaration) {
emitExportMemberAssignment(<ClassDeclaration>node);
}
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile && node.name) {
emitExportMemberAssignments(node.name);
}
}
function emitClassMemberPrefix(node: ClassLikeDeclaration, member: Node) {
@@ -5509,7 +5520,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitEnd(node);
write(";");
}
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
if (modulekind !== ModuleKind.ES6 && node.parent === currentSourceFile) {
if (modulekind === ModuleKind.System && (node.flags & NodeFlags.Export)) {
// write the call to exporter for enum
writeLine();
@@ -5645,8 +5656,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
/*
* Some bundlers (SystemJS builder) sometimes want to rename dependencies.
* Here we check if alternative name was provided for a given moduleName and return it if possible.
* Some bundlers (SystemJS builder) sometimes want to rename dependencies.
* Here we check if alternative name was provided for a given moduleName and return it if possible.
*/
function tryRenameExternalModule(moduleName: LiteralExpression): string {
if (currentSourceFile.renamedDependencies && hasProperty(currentSourceFile.renamedDependencies, moduleName.text)) {
@@ -6594,7 +6605,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("}"); // execute
}
function emitSystemModule(node: SourceFile, startIndex: number): void {
function emitSystemModule(node: SourceFile): void {
collectExternalModuleInfo(node);
// System modules has the following shape
// System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
@@ -6639,6 +6650,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(`], function(${exportFunctionForFile}) {`);
writeLine();
increaseIndent();
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
emitEmitHelpers(node);
emitCaptureThisForNodeIfNecessary(node);
emitSystemModuleBody(node, dependencyGroups, startIndex);
@@ -6732,7 +6744,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(") {");
}
function emitAMDModule(node: SourceFile, startIndex: number) {
function emitAMDModule(node: SourceFile) {
emitEmitHelpers(node);
collectExternalModuleInfo(node);
@@ -6743,6 +6755,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true);
increaseIndent();
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
emitExportStarHelper();
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
@@ -6753,7 +6766,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("});");
}
function emitCommonJSModule(node: SourceFile, startIndex: number) {
function emitCommonJSModule(node: SourceFile) {
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
emitEmitHelpers(node);
collectExternalModuleInfo(node);
emitExportStarHelper();
@@ -6763,7 +6777,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitExportEquals(/*emitAsReturn*/ false);
}
function emitUMDModule(node: SourceFile, startIndex: number) {
function emitUMDModule(node: SourceFile) {
emitEmitHelpers(node);
collectExternalModuleInfo(node);
@@ -6782,6 +6796,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
})(`);
emitAMDFactoryHeader(dependencyNames);
increaseIndent();
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
emitExportStarHelper();
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
@@ -6792,11 +6807,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("});");
}
function emitES6Module(node: SourceFile, startIndex: number) {
function emitES6Module(node: SourceFile) {
externalImports = undefined;
exportSpecifiers = undefined;
exportEquals = undefined;
hasExportStars = false;
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
emitEmitHelpers(node);
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
@@ -6985,14 +7001,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitShebang();
emitDetachedComments(node);
// emit prologue directives prior to __extends
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
if (isExternalModule(node) || compilerOptions.isolatedModules) {
let emitModule = moduleEmitDelegates[modulekind] || moduleEmitDelegates[ModuleKind.CommonJS];
emitModule(node, startIndex);
emitModule(node);
}
else {
// emit prologue directives prior to __extends
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
externalImports = undefined;
exportSpecifiers = undefined;
exportEquals = undefined;
@@ -7070,7 +7085,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
return shouldEmitEnumDeclaration(<EnumDeclaration>node);
}
// If the node is emitted in specialized fashion, dont emit comments as this node will handle
// If the node is emitted in specialized fashion, dont emit comments as this node will handle
// emitting comments when emitting itself
Debug.assert(!isSpecializedCommentHandling(node));
+34 -8
View File
@@ -57,11 +57,17 @@ namespace ts {
return visitNode(cbNode, (<TypeParameterDeclaration>node).name) ||
visitNode(cbNode, (<TypeParameterDeclaration>node).constraint) ||
visitNode(cbNode, (<TypeParameterDeclaration>node).expression);
case SyntaxKind.ShorthandPropertyAssignment:
return visitNodes(cbNodes, node.decorators) ||
visitNodes(cbNodes, node.modifiers) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).name) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).questionToken) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).equalsToken) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
case SyntaxKind.Parameter:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
return visitNodes(cbNodes, node.decorators) ||
@@ -856,7 +862,7 @@ namespace ts {
let saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
// Note: it is not actually necessary to save/restore the context flags here. That's
// because the saving/restorating of these flags happens naturally through the recursive
// because the saving/restoring of these flags happens naturally through the recursive
// descent nature of our parser. However, we still store this here just so we can
// assert that that invariant holds.
let saveContextFlags = contextFlags;
@@ -1124,7 +1130,15 @@ namespace ts {
if (token === SyntaxKind.DefaultKeyword) {
return nextTokenIsClassOrFunction();
}
if (token === SyntaxKind.StaticKeyword) {
nextToken();
return canFollowModifier();
}
nextToken();
if (scanner.hasPrecedingLineBreak()) {
return false;
}
return canFollowModifier();
}
@@ -3750,11 +3764,23 @@ namespace ts {
return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
}
// Parse to check if it is short-hand property assignment or normal property assignment
if ((token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBraceToken) && tokenIsIdentifier) {
// check if it is short-hand property assignment or normal property assignment
// NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
// CoverInitializedName[Yield] :
// IdentifierReference[?Yield] Initializer[In, ?Yield]
// this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
const isShorthandPropertyAssignment =
tokenIsIdentifier && (token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBraceToken || token === SyntaxKind.EqualsToken);
if (isShorthandPropertyAssignment) {
let shorthandDeclaration = <ShorthandPropertyAssignment>createNode(SyntaxKind.ShorthandPropertyAssignment, fullStart);
shorthandDeclaration.name = <Identifier>propertyName;
shorthandDeclaration.questionToken = questionToken;
const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken);
if (equalsToken) {
shorthandDeclaration.equalsToken = equalsToken;
shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
}
return finishNode(shorthandDeclaration);
}
else {
@@ -4157,8 +4183,12 @@ namespace ts {
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
return nextTokenIsIdentifierOrStringLiteralOnSameLine();
case SyntaxKind.AbstractKeyword:
case SyntaxKind.AsyncKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.PublicKeyword:
nextToken();
// ASI takes effect for this modifier.
if (scanner.hasPrecedingLineBreak()) {
@@ -4178,11 +4208,7 @@ namespace ts {
}
continue;
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.StaticKeyword:
case SyntaxKind.AbstractKeyword:
nextToken();
continue;
default:
+12 -2
View File
@@ -564,6 +564,10 @@ namespace ts {
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
name: Identifier;
questionToken?: Node;
// used when ObjectLiteralExpression is used in ObjectAssignmentPattern
// it is grammar error to appear in actual object initializer
equalsToken?: Node;
objectAssignmentInitializer?: Expression;
}
// SyntaxKind.VariableDeclaration
@@ -1600,7 +1604,6 @@ namespace ts {
isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult;
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
getBlockScopedVariableId(node: Identifier): number;
getReferencedValueDeclaration(reference: Identifier): Declaration;
getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind;
isOptionalParameter(node: ParameterDeclaration): boolean;
@@ -1882,7 +1885,7 @@ namespace ts {
}
export interface TupleType extends ObjectType {
elementTypes: Type[]; // Element types
elementTypes: Type[]; // Element types
}
export interface UnionOrIntersectionType extends Type {
@@ -1897,6 +1900,13 @@ namespace ts {
export interface IntersectionType extends UnionOrIntersectionType { }
/* @internal */
// An instantiated anonymous type has a target and a mapper
export interface AnonymousType extends ObjectType {
target?: AnonymousType; // Instantiation target
mapper?: TypeMapper; // Instantiation mapper
}
/* @internal */
// Resolved object, union, or intersection type
export interface ResolvedType extends ObjectType, UnionOrIntersectionType {
+13 -6
View File
@@ -100,6 +100,8 @@ namespace FourSlash {
end: number;
}
export import IndentStyle = ts.IndentStyle;
let entityMap: ts.Map<string> = {
"&": "&amp;",
"\"": "&quot;",
@@ -309,6 +311,7 @@ namespace FourSlash {
TabSize: 4,
NewLineCharacter: Harness.IO.newLine(),
ConvertTabsToSpaces: true,
IndentStyle: ts.IndentStyle.Smart,
InsertSpaceAfterCommaDelimiter: true,
InsertSpaceAfterSemicolonInForStatements: true,
InsertSpaceBeforeAndAfterBinaryOperators: true,
@@ -1695,24 +1698,28 @@ namespace FourSlash {
}
}
private getIndentation(fileName: string, position: number): number {
return this.languageService.getIndentationAtPosition(fileName, position, this.formatCodeOptions);
private getIndentation(fileName: string, position: number, indentStyle: ts.IndentStyle): number {
let formatOptions = ts.clone(this.formatCodeOptions);
formatOptions.IndentStyle = indentStyle;
return this.languageService.getIndentationAtPosition(fileName, position, formatOptions);
}
public verifyIndentationAtCurrentPosition(numberOfSpaces: number) {
public verifyIndentationAtCurrentPosition(numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart) {
this.taoInvalidReason = "verifyIndentationAtCurrentPosition NYI";
let actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition);
let actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition, indentStyle);
let lineCol = this.getLineColStringAtPosition(this.currentCaretPosition);
if (actual !== numberOfSpaces) {
this.raiseError(`verifyIndentationAtCurrentPosition failed at ${lineCol} - expected: ${numberOfSpaces}, actual: ${actual}`);
}
}
public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number) {
public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart) {
this.taoInvalidReason = "verifyIndentationAtPosition NYI";
let actual = this.getIndentation(fileName, position);
let actual = this.getIndentation(fileName, position, indentStyle);
let lineCol = this.getLineColStringAtPosition(position);
if (actual !== numberOfSpaces) {
this.raiseError(`verifyIndentationAtPosition failed at ${lineCol} - expected: ${numberOfSpaces}, actual: ${actual}`);
+3 -1
View File
@@ -57,7 +57,9 @@ class TypeWriterWalker {
symbolString += ", ";
let declSourceFile = declaration.getSourceFile();
let declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos);
symbolString += `Decl(${ ts.getBaseFileName(declSourceFile.fileName) }, ${ declLineAndCharacter.line }, ${ declLineAndCharacter.character })`;
let fileName = ts.getBaseFileName(declSourceFile.fileName);
let isLibFile = /lib(.*)\.d\.ts/i.test(fileName);
symbolString += `Decl(${ fileName }, ${ isLibFile ? "--" : declLineAndCharacter.line }, ${ isLibFile ? "--" : declLineAndCharacter.character })`;
}
}
symbolString += ")";
+5 -106
View File
@@ -1067,7 +1067,7 @@ declare var CanvasPattern: {
interface CanvasRenderingContext2D {
canvas: HTMLCanvasElement;
fillStyle: any;
fillStyle: string | CanvasGradient | CanvasPattern;
font: string;
globalAlpha: number;
globalCompositeOperation: string;
@@ -1082,7 +1082,7 @@ interface CanvasRenderingContext2D {
shadowColor: string;
shadowOffsetX: number;
shadowOffsetY: number;
strokeStyle: any;
strokeStyle: string | CanvasGradient | CanvasPattern;
textAlign: string;
textBaseline: string;
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
@@ -2450,8 +2450,6 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven
importNode(importedNode: Node, deep: boolean): Node;
msElementsFromPoint(x: number, y: number): NodeList;
msElementsFromRect(left: number, top: number, width: number, height: number): NodeList;
msGetPrintDocumentForNamedFlow(flowName: string): Document;
msSetPrintDocumentUriForNamedFlow(flowName: string, uri: string): void;
/**
* Opens a new window and loads a document specified by a given URL. Also, opens a new window that uses the url parameter and the name parameter to collect the output of the write method and the writeln method.
* @param url Specifies a MIME type for the document.
@@ -7273,27 +7271,6 @@ declare var MSHTMLWebViewElement: {
new(): MSHTMLWebViewElement;
}
interface MSHeaderFooter {
URL: string;
dateLong: string;
dateShort: string;
font: string;
htmlFoot: string;
htmlHead: string;
page: number;
pageTotal: number;
textFoot: string;
textHead: string;
timeLong: string;
timeShort: string;
title: string;
}
declare var MSHeaderFooter: {
prototype: MSHeaderFooter;
new(): MSHeaderFooter;
}
interface MSInputMethodContext extends EventTarget {
compositionEndOffset: number;
compositionStartOffset: number;
@@ -7452,24 +7429,6 @@ declare var MSPointerEvent: {
new(typeArg: string, eventInitDict?: PointerEventInit): MSPointerEvent;
}
interface MSPrintManagerTemplatePrinter extends MSTemplatePrinter, EventTarget {
percentScale: number;
showHeaderFooter: boolean;
shrinkToFit: boolean;
drawPreviewPage(element: HTMLElement, pageNumber: number): void;
endPrint(): void;
getPrintTaskOptionValue(key: string): any;
invalidatePreview(): void;
setPageCount(pageCount: number): void;
startPrint(): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
declare var MSPrintManagerTemplatePrinter: {
prototype: MSPrintManagerTemplatePrinter;
new(): MSPrintManagerTemplatePrinter;
}
interface MSRangeCollection {
length: number;
item(index: number): Range;
@@ -7517,63 +7476,6 @@ declare var MSStreamReader: {
new(): MSStreamReader;
}
interface MSTemplatePrinter {
collate: boolean;
copies: number;
currentPage: boolean;
currentPageAvail: boolean;
duplex: boolean;
footer: string;
frameActive: boolean;
frameActiveEnabled: boolean;
frameAsShown: boolean;
framesetDocument: boolean;
header: string;
headerFooterFont: string;
marginBottom: number;
marginLeft: number;
marginRight: number;
marginTop: number;
orientation: string;
pageFrom: number;
pageHeight: number;
pageTo: number;
pageWidth: number;
selectedPages: boolean;
selection: boolean;
selectionEnabled: boolean;
unprintableBottom: number;
unprintableLeft: number;
unprintableRight: number;
unprintableTop: number;
usePrinterCopyCollate: boolean;
createHeaderFooter(): MSHeaderFooter;
deviceSupports(property: string): any;
ensurePrintDialogDefaults(): boolean;
getPageMarginBottom(pageRule: CSSPageRule, pageWidth: number, pageHeight: number): any;
getPageMarginBottomImportant(pageRule: CSSPageRule): boolean;
getPageMarginLeft(pageRule: CSSPageRule, pageWidth: number, pageHeight: number): any;
getPageMarginLeftImportant(pageRule: CSSPageRule): boolean;
getPageMarginRight(pageRule: CSSPageRule, pageWidth: number, pageHeight: number): any;
getPageMarginRightImportant(pageRule: CSSPageRule): boolean;
getPageMarginTop(pageRule: CSSPageRule, pageWidth: number, pageHeight: number): any;
getPageMarginTopImportant(pageRule: CSSPageRule): boolean;
printBlankPage(): void;
printNonNative(document: any): boolean;
printNonNativeFrames(document: any, activeFrame: boolean): void;
printPage(element: HTMLElement): void;
showPageSetupDialog(): boolean;
showPrintDialog(): boolean;
startDoc(title: string): boolean;
stopDoc(): void;
updatePageStatus(status: number): void;
}
declare var MSTemplatePrinter: {
prototype: MSTemplatePrinter;
new(): MSTemplatePrinter;
}
interface MSWebViewAsyncOperation extends EventTarget {
error: DOMError;
oncomplete: (ev: Event) => any;
@@ -8718,7 +8620,6 @@ declare var SVGDescElement: {
interface SVGElement extends Element {
id: string;
className: any;
onclick: (ev: MouseEvent) => any;
ondblclick: (ev: MouseEvent) => any;
onfocusin: (ev: FocusEvent) => any;
@@ -8732,6 +8633,7 @@ interface SVGElement extends Element {
ownerSVGElement: SVGSVGElement;
viewportElement: SVGElement;
xmlbase: string;
className: any;
addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void;
@@ -11871,7 +11773,6 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
locationbar: BarProp;
menubar: BarProp;
msAnimationStartTime: number;
msTemplatePrinter: MSTemplatePrinter;
name: string;
navigator: Navigator;
offscreenBuffering: string | boolean;
@@ -12608,7 +12509,6 @@ interface XMLHttpRequestEventTarget {
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
interface NodeListOf<TNode extends Node> extends NodeList {
length: number;
item(index: number): TNode;
@@ -12629,8 +12529,6 @@ interface EventListenerObject {
handleEvent(evt: Event): void;
}
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
interface MessageEventInit extends EventInit {
data?: any;
origin?: string;
@@ -12646,6 +12544,8 @@ interface ProgressEventInit extends EventInit {
total?: number;
}
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
interface ErrorEventHandler {
(message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void;
}
@@ -12706,7 +12606,6 @@ declare var location: Location;
declare var locationbar: BarProp;
declare var menubar: BarProp;
declare var msAnimationStartTime: number;
declare var msTemplatePrinter: MSTemplatePrinter;
declare var name: string;
declare var navigator: Navigator;
declare var offscreenBuffering: string | boolean;
+2 -3
View File
@@ -894,7 +894,6 @@ interface WorkerUtils extends Object, WindowBase64 {
setTimeout(handler: any, timeout?: any, ...args: any[]): number;
}
interface BlobPropertyBag {
type?: string;
endings?: string;
@@ -909,8 +908,6 @@ interface EventListenerObject {
handleEvent(evt: Event): void;
}
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
interface MessageEventInit extends EventInit {
data?: any;
origin?: string;
@@ -926,6 +923,8 @@ interface ProgressEventInit extends EventInit {
total?: number;
}
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
interface ErrorEventHandler {
(message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void;
}
+1 -1
View File
@@ -1177,6 +1177,7 @@ namespace ts.server {
TabSize: 4,
NewLineCharacter: ts.sys ? ts.sys.newLine : '\n',
ConvertTabsToSpaces: true,
IndentStyle: ts.IndentStyle.Smart,
InsertSpaceAfterCommaDelimiter: true,
InsertSpaceAfterSemicolonInForStatements: true,
InsertSpaceBeforeAndAfterBinaryOperators: true,
@@ -1187,7 +1188,6 @@ namespace ts.server {
PlaceOpenBraceOnNewLineForFunctions: false,
PlaceOpenBraceOnNewLineForControlBlocks: false,
}
}
export interface LineCollection {
+1
View File
@@ -606,6 +606,7 @@ namespace ts.server {
TabSize: formatOptions.TabSize,
NewLineCharacter: "\n",
ConvertTabsToSpaces: formatOptions.ConvertTabsToSpaces,
IndentStyle: ts.IndentStyle.Smart,
};
var indentPosition =
compilerService.languageService.getIndentationAtPosition(file, position, editorOptions);
+6 -2
View File
@@ -216,8 +216,10 @@ namespace ts.formatting {
// Async functions
public SpaceBetweenAsyncAndFunctionKeyword: Rule;
// Tagged template string
// Template strings
public SpaceBetweenTagAndTemplateString: Rule;
public NoSpaceAfterTemplateHeadAndMiddle: Rule;
public NoSpaceBeforeTemplateMiddleAndTail: Rule;
constructor() {
///
@@ -371,6 +373,8 @@ namespace ts.formatting {
// template string
this.SpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
// These rules are higher in priority than user-configurable rules.
this.HighPriorityCommonRules =
@@ -399,7 +403,7 @@ namespace ts.formatting {
this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator,
this.SpaceAfterVoidOperator,
this.SpaceBetweenAsyncAndFunctionKeyword,
this.SpaceBetweenTagAndTemplateString,
this.SpaceBetweenTagAndTemplateString, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail,
// TypeScript-specific rules
this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport,
+29 -3
View File
@@ -13,6 +13,12 @@ namespace ts.formatting {
return 0; // past EOF
}
// no indentation when the indent style is set to none,
// so we can return fast
if (options.IndentStyle === IndentStyle.None) {
return 0;
}
let precedingToken = findPrecedingToken(position, sourceFile);
if (!precedingToken) {
return 0;
@@ -26,6 +32,26 @@ namespace ts.formatting {
let lineAtPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
// indentation is first non-whitespace character in a previous line
// for block indentation, we should look for a line which contains something that's not
// whitespace.
if (options.IndentStyle === IndentStyle.Block) {
// move backwards until we find a line with a non-whitespace character,
// then find the first non-whitespace character for that line.
let current = position;
while (current > 0){
let char = sourceFile.text.charCodeAt(current);
if (!isWhiteSpace(char) && !isLineBreak(char)) {
break;
}
current--;
}
let lineStart = ts.getLineStartPositionForPosition(current, sourceFile);
return SmartIndenter.findFirstNonWhitespaceColumn(lineStart, current, sourceFile, options);
}
if (precedingToken.kind === SyntaxKind.CommaToken && precedingToken.parent.kind !== SyntaxKind.BinaryExpression) {
// previous token is comma that separates items in list - find the previous item and try to derive indentation from it
let actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options);
@@ -218,7 +244,7 @@ namespace ts.formatting {
function getStartLineAndCharacterForNode(n: Node, sourceFile: SourceFile): LineAndCharacter {
return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile));
}
export function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFile): boolean {
if (parent.kind === SyntaxKind.IfStatement && (<IfStatement>parent).elseStatement === child) {
let elseKeyword = findChildOfKind(parent, SyntaxKind.ElseKeyword, sourceFile);
@@ -319,7 +345,7 @@ namespace ts.formatting {
}
return Value.Unknown;
function getStartingExpression(node: PropertyAccessExpression | CallExpression | ElementAccessExpression) {
while (true) {
switch (node.kind) {
@@ -464,4 +490,4 @@ namespace ts.formatting {
}
}
}
}
}
+19 -6
View File
@@ -1189,6 +1189,13 @@ namespace ts {
TabSize: number;
NewLineCharacter: string;
ConvertTabsToSpaces: boolean;
IndentStyle: IndentStyle;
}
export enum IndentStyle {
None = 0,
Block = 1,
Smart = 2,
}
export interface FormatCodeOptions extends EditorOptions {
@@ -1850,8 +1857,8 @@ namespace ts {
// so pass --noResolve to avoid reporting missing file errors.
options.noResolve = true;
// Parse
let inputFileName = transpileOptions.fileName || "module.ts";
// if jsx is specified then treat file as .tsx
let inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts");
let sourceFile = createSourceFile(inputFileName, input, options.target);
if (transpileOptions.moduleName) {
sourceFile.moduleName = transpileOptions.moduleName;
@@ -3683,14 +3690,20 @@ namespace ts {
// Previous token may have been a keyword that was converted to an identifier.
switch (contextToken.getText()) {
case "abstract":
case "async":
case "class":
case "interface":
case "const":
case "declare":
case "enum":
case "function":
case "var":
case "static":
case "interface":
case "let":
case "const":
case "private":
case "protected":
case "public":
case "static":
case "var":
case "yield":
return true;
}