diff --git a/TypeScript b/TypeScript index e16326d..9ac13ab 160000 --- a/TypeScript +++ b/TypeScript @@ -1 +1 @@ -Subproject commit e16326de8b910926f95bcf9f16aed0db5265d1fb +Subproject commit 9ac13abfd196f662ce606d8d99cb8791c2ad61fe diff --git a/bin/ntypescript.d.ts b/bin/ntypescript.d.ts index f237b22..ff01afe 100644 --- a/bin/ntypescript.d.ts +++ b/bin/ntypescript.d.ts @@ -715,11 +715,17 @@ declare namespace ts { properties: NodeArray; multiLine?: boolean; } + type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; + type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; interface PropertyAccessExpression extends MemberExpression, Declaration { expression: LeftHandSideExpression; name: Identifier; } - type IdentifierOrPropertyAccess = Identifier | PropertyAccessExpression; + /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ + interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { + _propertyAccessExpressionLikeQualifiedNameBrand?: any; + expression: EntityNameExpression; + } interface ElementAccessExpression extends MemberExpression { expression: LeftHandSideExpression; argumentExpression?: Expression; @@ -1422,7 +1428,7 @@ declare namespace ts { writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult; - isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult; + isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; getReferencedValueDeclaration(reference: Identifier): Declaration; getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind; @@ -1430,7 +1436,7 @@ declare namespace ts { moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean; isArgumentsLocalBinding(node: Identifier): boolean; getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile; - getTypeReferenceDirectivesForEntityName(name: EntityName | PropertyAccessExpression): string[]; + getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[]; getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[]; } enum SymbolFlags { @@ -1681,6 +1687,7 @@ declare namespace ts { } interface TupleType extends ObjectType { elementTypes: Type[]; + thisType?: Type; } interface UnionOrIntersectionType extends Type { types: Type[]; @@ -2251,7 +2258,9 @@ declare namespace ts { * returns a truthy value, then returns that value. * If no such value is found, the callback is applied to each element of array and undefined is returned. */ - function forEach(array: T[], callback: (element: T, index: number) => U): U; + function forEach(array: T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined; + /** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */ + function find(array: T[], callback: (element: T, index: number) => U | undefined): U; function contains(array: T[], value: T): boolean; function indexOf(array: T[], value: T): number; function indexOfAnyCharCode(text: string, charCodes: number[], start?: number): number; @@ -2584,7 +2593,7 @@ declare namespace ts { * Determines whether a node is a property or element access expression for super. */ function isSuperPropertyOrElementAccess(node: Node): boolean; - function getEntityNameFromTypeNode(node: TypeNode): EntityName | Expression; + function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression; function getInvokedExpression(node: CallLikeExpression): Expression; function nodeCanBeDecorated(node: Node): boolean; function nodeIsDecorated(node: Node): boolean; @@ -2637,6 +2646,7 @@ declare namespace ts { function isLiteralComputedPropertyDeclarationName(node: Node): boolean; function isIdentifierName(node: Identifier): boolean; function isAliasSymbolDeclaration(node: Node): boolean; + function exportAssignmentIsAlias(node: ExportAssignment): boolean; function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments; function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration): NodeArray; function getInterfaceBaseTypeNodes(node: InterfaceDeclaration): NodeArray; @@ -2761,7 +2771,7 @@ declare namespace ts { function isLeftHandSideExpression(expr: Expression): boolean; function isAssignmentOperator(token: SyntaxKind): boolean; function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean; - function isSupportedExpressionWithTypeArguments(node: ExpressionWithTypeArguments): boolean; + function isEntityNameExpression(node: Expression): node is EntityNameExpression; function isRightSideOfQualifiedNameOrPropertyAccess(node: Node): boolean; function isEmptyObjectLiteralOrArrayLiteral(expression: Node): boolean; function getLocalSymbolForExportDefault(symbol: Symbol): Symbol; diff --git a/bin/ntypescript.js b/bin/ntypescript.js index 99a3bf1..1f3c477 100644 --- a/bin/ntypescript.js +++ b/bin/ntypescript.js @@ -1083,6 +1083,17 @@ var ts; return undefined; } ts.forEach = forEach; + /** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */ + function find(array, callback) { + for (var i = 0, len = array.length; i < len; i++) { + var result = callback(array[i], i); + if (result) { + return result; + } + } + Debug.fail(); + } + ts.find = find; function contains(array, value) { if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { @@ -3722,6 +3733,7 @@ var ts; case 155 /* TypeReference */: return node.typeName; case 194 /* ExpressionWithTypeArguments */: + ts.Debug.assert(isEntityNameExpression(node.expression)); return node.expression; case 69 /* Identifier */: case 139 /* QualifiedName */: @@ -4356,8 +4368,8 @@ var ts; // import * as from ... // import { x as } from ... // export { x as } from ... - // export = ... - // export default ... + // export = + // export default function isAliasSymbolDeclaration(node) { return node.kind === 229 /* ImportEqualsDeclaration */ || node.kind === 228 /* NamespaceExportDeclaration */ || @@ -4365,9 +4377,13 @@ var ts; node.kind === 232 /* NamespaceImport */ || node.kind === 234 /* ImportSpecifier */ || node.kind === 238 /* ExportSpecifier */ || - node.kind === 235 /* ExportAssignment */ && node.expression.kind === 69 /* Identifier */; + node.kind === 235 /* ExportAssignment */ && exportAssignmentIsAlias(node); } ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration; + function exportAssignmentIsAlias(node) { + return isEntityNameExpression(node.expression); + } + ts.exportAssignmentIsAlias = exportAssignmentIsAlias; function getClassExtendsHeritageClauseElement(node) { var heritageClause = getHeritageClause(node.heritageClauses, 83 /* ExtendsKeyword */); return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined; @@ -5254,23 +5270,11 @@ var ts; isClassLike(node.parent.parent); } ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause; - // Returns false if this heritage clause element's expression contains something unsupported - // (i.e. not a name or dotted name). - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 69 /* Identifier */) { - return true; - } - else if (isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } + function isEntityNameExpression(node) { + return node.kind === 69 /* Identifier */ || + node.kind === 172 /* PropertyAccessExpression */ && isEntityNameExpression(node.expression); } + ts.isEntityNameExpression = isEntityNameExpression; function isRightSideOfQualifiedNameOrPropertyAccess(node) { return (node.parent.kind === 139 /* QualifiedName */ && node.parent.right === node) || (node.parent.kind === 172 /* PropertyAccessExpression */ && node.parent.name === node); @@ -16020,18 +16024,15 @@ var ts; bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\""); } function bindExportAssignment(node) { - var boundExpression = node.kind === 235 /* ExportAssignment */ ? node.expression : node.right; if (!container.symbol || !container.symbol.exports) { // Export assignment in some sort of block construct bindAnonymousDeclaration(node, 8388608 /* Alias */, getDeclarationName(node)); } - else if (boundExpression.kind === 69 /* Identifier */ && node.kind === 235 /* ExportAssignment */) { - // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); - } else { - // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + var flags = node.kind === 235 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node) + ? 8388608 /* Alias */ + : 4 /* Property */; + declareSymbol(container.symbol.exports, container.symbol, node, flags, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); } } function bindNamespaceExportDeclaration(node) { @@ -17131,8 +17132,9 @@ var ts; } if (!result) { if (nameNotFoundMessage) { - if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && - !checkAndReportErrorForExtendingInterface(errorLocation)) { + if (!errorLocation || + !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && + !checkAndReportErrorForExtendingInterface(errorLocation)) { error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg)); } } @@ -17175,7 +17177,7 @@ var ts; return result; } function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) { - if (!errorLocation || (errorLocation.kind === 69 /* Identifier */ && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) { + if ((errorLocation.kind === 69 /* Identifier */ && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) { return false; } var container = ts.getThisContainer(errorLocation, /* includeArrowFunctions */ true); @@ -17207,27 +17209,28 @@ var ts; return false; } function checkAndReportErrorForExtendingInterface(errorLocation) { - var parentClassExpression = errorLocation; - while (parentClassExpression) { - var kind = parentClassExpression.kind; - if (kind === 69 /* Identifier */ || kind === 172 /* PropertyAccessExpression */) { - parentClassExpression = parentClassExpression.parent; - continue; - } - if (kind === 194 /* ExpressionWithTypeArguments */) { - break; - } - return false; - } - if (!parentClassExpression) { - return false; - } - var expression = parentClassExpression.expression; - if (resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)) { + var expression = getEntityNameForExtendingInterface(errorLocation); + var isError = !!(expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)); + if (isError) { error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression)); - return true; } - return false; + return isError; + } + /** + * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression, + * but returns undefined if that expression is not an EntityNameExpression. + */ + function getEntityNameForExtendingInterface(node) { + switch (node.kind) { + case 69 /* Identifier */: + case 172 /* PropertyAccessExpression */: + return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined; + case 194 /* ExpressionWithTypeArguments */: + ts.Debug.assert(ts.isEntityNameExpression(node.expression)); + return node.expression; + default: + return undefined; + } } function checkResolvedBlockScopedVariable(result, errorLocation) { ts.Debug.assert((result.flags & 2 /* BlockScopedVariable */) !== 0); @@ -17265,7 +17268,7 @@ var ts; } } function getDeclarationOfAliasSymbol(symbol) { - return ts.forEach(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); + return ts.find(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); } function getTargetOfImportEqualsDeclaration(node) { if (node.moduleReference.kind === 240 /* ExternalModuleReference */) { @@ -17706,8 +17709,8 @@ var ts; } function createType(flags) { var result = new Type(checker, flags); - result.id = typeCount; typeCount++; + result.id = typeCount; return result; } function createIntrinsicType(kind, intrinsicName) { @@ -19662,7 +19665,7 @@ var ts; if (baseTypeNodes) { for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) { var node = baseTypeNodes_1[_b]; - if (ts.isSupportedExpressionWithTypeArguments(node)) { + if (ts.isEntityNameExpression(node.expression)) { var baseSymbol = resolveEntityName(node.expression, 793064 /* Type */, /*ignoreErrors*/ true); if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) { return false; @@ -19970,6 +19973,9 @@ var ts; if (type.flags & 131072 /* Reference */) { return createTypeReference(type.target, ts.concatenate(type.typeArguments, [thisArgument || type.target.thisType])); } + if (type.flags & 262144 /* Tuple */) { + return createTupleType(type.elementTypes, thisArgument); + } return type; } function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) { @@ -20065,7 +20071,8 @@ var ts; function resolveTupleTypeMembers(type) { var arrayElementType = getUnionType(type.elementTypes); // Make the tuple type itself the 'this' type by including an extra type argument - var arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type])); + // (Unless it's provided in the case that the tuple is a type parameter constraint) + var arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type.thisType || type])); var members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo); @@ -20841,24 +20848,27 @@ var ts; return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 141 /* TypeParameter */).parent); } function getTypeListId(types) { + var result = ""; if (types) { - switch (types.length) { - case 1: - return "" + types[0].id; - case 2: - return types[0].id + "," + types[1].id; - default: - var result = ""; - for (var i = 0; i < types.length; i++) { - if (i > 0) { - result += ","; - } - result += types[i].id; - } - return result; + var length_3 = types.length; + var i = 0; + while (i < length_3) { + var startId = types[i].id; + var count = 1; + while (i + count < length_3 && types[i + count].id === startId + count) { + count++; + } + if (result.length) { + result += ","; + } + result += startId; + if (count > 1) { + result += ":" + count; + } + i += count; } } - return ""; + return result; } // This function is used to propagate certain flags when creating new object type references and union types. // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type @@ -20945,8 +20955,9 @@ var ts; case 194 /* ExpressionWithTypeArguments */: // We only support expressions that are simple qualified names. For other // expressions this produces undefined. - if (ts.isSupportedExpressionWithTypeArguments(node)) { - return node.expression; + var expr = node.expression; + if (ts.isEntityNameExpression(expr)) { + return expr; } } return undefined; @@ -20984,14 +20995,14 @@ var ts; var typeReferenceName = getTypeReferenceName(node); symbol = resolveTypeReferenceName(node, typeReferenceName); type = getTypeReferenceType(node, symbol); - links.resolvedSymbol = symbol; - links.resolvedType = type; } else { // We only support expressions that are simple qualified names. For other expressions this produces undefined. - var typeNameOrExpression = node.kind === 155 /* TypeReference */ ? node.typeName : - ts.isSupportedExpressionWithTypeArguments(node) ? node.expression : - undefined; + var typeNameOrExpression = node.kind === 155 /* TypeReference */ + ? node.typeName + : ts.isEntityNameExpression(node.expression) + ? node.expression + : undefined; symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, 793064 /* Type */) || unknownSymbol; type = symbol === unknownSymbol ? unknownType : symbol.flags & (32 /* Class */ | 64 /* Interface */) ? getTypeFromClassOrInterfaceReference(node, symbol) : @@ -21096,14 +21107,15 @@ var ts; } return links.resolvedType; } - function createTupleType(elementTypes) { - var id = getTypeListId(elementTypes); - return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes)); + function createTupleType(elementTypes, thisType) { + var id = getTypeListId(elementTypes) + "," + (thisType ? thisType.id : 0); + return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType)); } - function createNewTupleType(elementTypes) { + function createNewTupleType(elementTypes, thisType) { var propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0); var type = createObjectType(262144 /* Tuple */ | propagatedFlags); type.elementTypes = elementTypes; + type.thisType = thisType; return type; } function getTypeFromTupleTypeNode(node) { @@ -31181,7 +31193,7 @@ var ts; if (implementedTypeNodes) { for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) { var typeRefNode = implementedTypeNodes_1[_b]; - if (!ts.isSupportedExpressionWithTypeArguments(typeRefNode)) { + if (!ts.isEntityNameExpression(typeRefNode.expression)) { error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(typeRefNode); @@ -31396,7 +31408,7 @@ var ts; checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { - if (!ts.isSupportedExpressionWithTypeArguments(heritageElement)) { + if (!ts.isEntityNameExpression(heritageElement.expression)) { error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(heritageElement); @@ -31822,19 +31834,20 @@ var ts; } } function getFirstIdentifier(node) { - while (true) { - if (node.kind === 139 /* QualifiedName */) { - node = node.left; - } - else if (node.kind === 172 /* PropertyAccessExpression */) { - node = node.expression; - } - else { - break; - } + switch (node.kind) { + case 69 /* Identifier */: + return node; + case 139 /* QualifiedName */: + do { + node = node.left; + } while (node.kind !== 69 /* Identifier */); + return node; + case 172 /* PropertyAccessExpression */: + do { + node = node.expression; + } while (node.kind !== 69 /* Identifier */); + return node; } - ts.Debug.assert(node.kind === 69 /* Identifier */); - return node; } function checkExternalImportOrExportDeclaration(node) { var moduleName = ts.getExternalModuleName(node); @@ -32479,17 +32492,15 @@ var ts; default: } } - if (entityName.parent.kind === 235 /* ExportAssignment */) { + if (entityName.parent.kind === 235 /* ExportAssignment */ && ts.isEntityNameExpression(entityName)) { return resolveEntityName(entityName, /*all meanings*/ 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 8388608 /* Alias */); } - if (entityName.kind !== 172 /* PropertyAccessExpression */) { - if (isInRightSideOfImportOrExportAssignment(entityName)) { - // Since we already checked for ExportAssignment, this really could only be an Import - var importEqualsDeclaration = ts.getAncestor(entityName, 229 /* ImportEqualsDeclaration */); - ts.Debug.assert(importEqualsDeclaration !== undefined); - return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); - } + if (entityName.kind !== 172 /* PropertyAccessExpression */ && isInRightSideOfImportOrExportAssignment(entityName)) { + // Since we already checked for ExportAssignment, this really could only be an Import + var importEqualsDeclaration = ts.getAncestor(entityName, 229 /* ImportEqualsDeclaration */); + ts.Debug.assert(importEqualsDeclaration !== undefined); + return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); } if (ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { entityName = entityName.parent; @@ -35821,7 +35832,7 @@ var ts; writeEntityName(entityName); } function emitExpressionWithTypeArguments(node) { - if (ts.isSupportedExpressionWithTypeArguments(node)) { + if (ts.isEntityNameExpression(node.expression)) { ts.Debug.assert(node.expression.kind === 69 /* Identifier */ || node.expression.kind === 172 /* PropertyAccessExpression */); emitEntityName(node.expression); if (node.typeArguments) { @@ -36335,7 +36346,7 @@ var ts; emitCommaList(typeReferences, emitTypeOfTypeReference); } function emitTypeOfTypeReference(node) { - if (ts.isSupportedExpressionWithTypeArguments(node)) { + if (ts.isEntityNameExpression(node.expression)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } else if (!isImplementsList && node.expression.kind === 93 /* NullKeyword */) { @@ -46905,9 +46916,9 @@ var ts; function reportDiagnosticWithColorAndContext(diagnostic, host) { var output = ""; if (diagnostic.file) { - var start = diagnostic.start, length_3 = diagnostic.length, file = diagnostic.file; + var start = diagnostic.start, length_4 = diagnostic.length, file = diagnostic.file; var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character; - var _b = ts.getLineAndCharacterOfPosition(file, start + length_3), lastLine = _b.line, lastLineChar = _b.character; + var _b = ts.getLineAndCharacterOfPosition(file, start + length_4), lastLine = _b.line, lastLineChar = _b.character; var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line; var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName; var hasMoreThanFiveLines = (lastLine - firstLine) >= 4; @@ -60104,7 +60115,7 @@ var ts; var lastEnd = 0; for (var i = 0, n = dense.length; i < n; i += 3) { var start = dense[i]; - var length_4 = dense[i + 1]; + var length_5 = dense[i + 1]; var type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { @@ -60113,8 +60124,8 @@ var ts; entries.push({ length: whitespaceLength_1, classification: TokenClass.Whitespace }); } } - entries.push({ length: length_4, classification: convertClassification(type) }); - lastEnd = start + length_4; + entries.push({ length: length_5, classification: convertClassification(type) }); + lastEnd = start + length_5; } var whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { diff --git a/bin/typescript.d.ts b/bin/typescript.d.ts index fb51f48..3df1dca 100644 --- a/bin/typescript.d.ts +++ b/bin/typescript.d.ts @@ -715,11 +715,17 @@ declare namespace ts { properties: NodeArray; multiLine?: boolean; } + type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; + type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; interface PropertyAccessExpression extends MemberExpression, Declaration { expression: LeftHandSideExpression; name: Identifier; } - type IdentifierOrPropertyAccess = Identifier | PropertyAccessExpression; + /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ + interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { + _propertyAccessExpressionLikeQualifiedNameBrand?: any; + expression: EntityNameExpression; + } interface ElementAccessExpression extends MemberExpression { expression: LeftHandSideExpression; argumentExpression?: Expression; @@ -1422,7 +1428,7 @@ declare namespace ts { writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult; - isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult; + isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; getReferencedValueDeclaration(reference: Identifier): Declaration; getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind; @@ -1430,7 +1436,7 @@ declare namespace ts { moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean; isArgumentsLocalBinding(node: Identifier): boolean; getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile; - getTypeReferenceDirectivesForEntityName(name: EntityName | PropertyAccessExpression): string[]; + getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[]; getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[]; } const enum SymbolFlags { @@ -1681,6 +1687,7 @@ declare namespace ts { } interface TupleType extends ObjectType { elementTypes: Type[]; + thisType?: Type; } interface UnionOrIntersectionType extends Type { types: Type[]; @@ -2251,7 +2258,9 @@ declare namespace ts { * returns a truthy value, then returns that value. * If no such value is found, the callback is applied to each element of array and undefined is returned. */ - function forEach(array: T[], callback: (element: T, index: number) => U): U; + function forEach(array: T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined; + /** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */ + function find(array: T[], callback: (element: T, index: number) => U | undefined): U; function contains(array: T[], value: T): boolean; function indexOf(array: T[], value: T): number; function indexOfAnyCharCode(text: string, charCodes: number[], start?: number): number; @@ -2584,7 +2593,7 @@ declare namespace ts { * Determines whether a node is a property or element access expression for super. */ function isSuperPropertyOrElementAccess(node: Node): boolean; - function getEntityNameFromTypeNode(node: TypeNode): EntityName | Expression; + function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression; function getInvokedExpression(node: CallLikeExpression): Expression; function nodeCanBeDecorated(node: Node): boolean; function nodeIsDecorated(node: Node): boolean; @@ -2637,6 +2646,7 @@ declare namespace ts { function isLiteralComputedPropertyDeclarationName(node: Node): boolean; function isIdentifierName(node: Identifier): boolean; function isAliasSymbolDeclaration(node: Node): boolean; + function exportAssignmentIsAlias(node: ExportAssignment): boolean; function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments; function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration): NodeArray; function getInterfaceBaseTypeNodes(node: InterfaceDeclaration): NodeArray; @@ -2761,7 +2771,7 @@ declare namespace ts { function isLeftHandSideExpression(expr: Expression): boolean; function isAssignmentOperator(token: SyntaxKind): boolean; function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean; - function isSupportedExpressionWithTypeArguments(node: ExpressionWithTypeArguments): boolean; + function isEntityNameExpression(node: Expression): node is EntityNameExpression; function isRightSideOfQualifiedNameOrPropertyAccess(node: Node): boolean; function isEmptyObjectLiteralOrArrayLiteral(expression: Node): boolean; function getLocalSymbolForExportDefault(symbol: Symbol): Symbol; diff --git a/bin/typescript.js b/bin/typescript.js index 06cbfc4..de9262d 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -1083,6 +1083,17 @@ var ts; return undefined; } ts.forEach = forEach; + /** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */ + function find(array, callback) { + for (var i = 0, len = array.length; i < len; i++) { + var result = callback(array[i], i); + if (result) { + return result; + } + } + Debug.fail(); + } + ts.find = find; function contains(array, value) { if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { @@ -3722,6 +3733,7 @@ var ts; case 155 /* TypeReference */: return node.typeName; case 194 /* ExpressionWithTypeArguments */: + ts.Debug.assert(isEntityNameExpression(node.expression)); return node.expression; case 69 /* Identifier */: case 139 /* QualifiedName */: @@ -4356,8 +4368,8 @@ var ts; // import * as from ... // import { x as } from ... // export { x as } from ... - // export = ... - // export default ... + // export = + // export default function isAliasSymbolDeclaration(node) { return node.kind === 229 /* ImportEqualsDeclaration */ || node.kind === 228 /* NamespaceExportDeclaration */ || @@ -4365,9 +4377,13 @@ var ts; node.kind === 232 /* NamespaceImport */ || node.kind === 234 /* ImportSpecifier */ || node.kind === 238 /* ExportSpecifier */ || - node.kind === 235 /* ExportAssignment */ && node.expression.kind === 69 /* Identifier */; + node.kind === 235 /* ExportAssignment */ && exportAssignmentIsAlias(node); } ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration; + function exportAssignmentIsAlias(node) { + return isEntityNameExpression(node.expression); + } + ts.exportAssignmentIsAlias = exportAssignmentIsAlias; function getClassExtendsHeritageClauseElement(node) { var heritageClause = getHeritageClause(node.heritageClauses, 83 /* ExtendsKeyword */); return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined; @@ -5254,23 +5270,11 @@ var ts; isClassLike(node.parent.parent); } ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause; - // Returns false if this heritage clause element's expression contains something unsupported - // (i.e. not a name or dotted name). - function isSupportedExpressionWithTypeArguments(node) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - ts.isSupportedExpressionWithTypeArguments = isSupportedExpressionWithTypeArguments; - function isSupportedExpressionWithTypeArgumentsRest(node) { - if (node.kind === 69 /* Identifier */) { - return true; - } - else if (isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } + function isEntityNameExpression(node) { + return node.kind === 69 /* Identifier */ || + node.kind === 172 /* PropertyAccessExpression */ && isEntityNameExpression(node.expression); } + ts.isEntityNameExpression = isEntityNameExpression; function isRightSideOfQualifiedNameOrPropertyAccess(node) { return (node.parent.kind === 139 /* QualifiedName */ && node.parent.right === node) || (node.parent.kind === 172 /* PropertyAccessExpression */ && node.parent.name === node); @@ -16020,18 +16024,15 @@ var ts; bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\""); } function bindExportAssignment(node) { - var boundExpression = node.kind === 235 /* ExportAssignment */ ? node.expression : node.right; if (!container.symbol || !container.symbol.exports) { // Export assignment in some sort of block construct bindAnonymousDeclaration(node, 8388608 /* Alias */, getDeclarationName(node)); } - else if (boundExpression.kind === 69 /* Identifier */ && node.kind === 235 /* ExportAssignment */) { - // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); - } else { - // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + var flags = node.kind === 235 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node) + ? 8388608 /* Alias */ + : 4 /* Property */; + declareSymbol(container.symbol.exports, container.symbol, node, flags, 0 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); } } function bindNamespaceExportDeclaration(node) { @@ -17131,8 +17132,9 @@ var ts; } if (!result) { if (nameNotFoundMessage) { - if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && - !checkAndReportErrorForExtendingInterface(errorLocation)) { + if (!errorLocation || + !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && + !checkAndReportErrorForExtendingInterface(errorLocation)) { error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg)); } } @@ -17175,7 +17177,7 @@ var ts; return result; } function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) { - if (!errorLocation || (errorLocation.kind === 69 /* Identifier */ && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) { + if ((errorLocation.kind === 69 /* Identifier */ && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) { return false; } var container = ts.getThisContainer(errorLocation, /* includeArrowFunctions */ true); @@ -17207,27 +17209,28 @@ var ts; return false; } function checkAndReportErrorForExtendingInterface(errorLocation) { - var parentClassExpression = errorLocation; - while (parentClassExpression) { - var kind = parentClassExpression.kind; - if (kind === 69 /* Identifier */ || kind === 172 /* PropertyAccessExpression */) { - parentClassExpression = parentClassExpression.parent; - continue; - } - if (kind === 194 /* ExpressionWithTypeArguments */) { - break; - } - return false; - } - if (!parentClassExpression) { - return false; - } - var expression = parentClassExpression.expression; - if (resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)) { + var expression = getEntityNameForExtendingInterface(errorLocation); + var isError = !!(expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)); + if (isError) { error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression)); - return true; } - return false; + return isError; + } + /** + * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression, + * but returns undefined if that expression is not an EntityNameExpression. + */ + function getEntityNameForExtendingInterface(node) { + switch (node.kind) { + case 69 /* Identifier */: + case 172 /* PropertyAccessExpression */: + return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined; + case 194 /* ExpressionWithTypeArguments */: + ts.Debug.assert(ts.isEntityNameExpression(node.expression)); + return node.expression; + default: + return undefined; + } } function checkResolvedBlockScopedVariable(result, errorLocation) { ts.Debug.assert((result.flags & 2 /* BlockScopedVariable */) !== 0); @@ -17265,7 +17268,7 @@ var ts; } } function getDeclarationOfAliasSymbol(symbol) { - return ts.forEach(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); + return ts.find(symbol.declarations, function (d) { return ts.isAliasSymbolDeclaration(d) ? d : undefined; }); } function getTargetOfImportEqualsDeclaration(node) { if (node.moduleReference.kind === 240 /* ExternalModuleReference */) { @@ -17706,8 +17709,8 @@ var ts; } function createType(flags) { var result = new Type(checker, flags); - result.id = typeCount; typeCount++; + result.id = typeCount; return result; } function createIntrinsicType(kind, intrinsicName) { @@ -19662,7 +19665,7 @@ var ts; if (baseTypeNodes) { for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) { var node = baseTypeNodes_1[_b]; - if (ts.isSupportedExpressionWithTypeArguments(node)) { + if (ts.isEntityNameExpression(node.expression)) { var baseSymbol = resolveEntityName(node.expression, 793064 /* Type */, /*ignoreErrors*/ true); if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) { return false; @@ -19970,6 +19973,9 @@ var ts; if (type.flags & 131072 /* Reference */) { return createTypeReference(type.target, ts.concatenate(type.typeArguments, [thisArgument || type.target.thisType])); } + if (type.flags & 262144 /* Tuple */) { + return createTupleType(type.elementTypes, thisArgument); + } return type; } function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) { @@ -20065,7 +20071,8 @@ var ts; function resolveTupleTypeMembers(type) { var arrayElementType = getUnionType(type.elementTypes); // Make the tuple type itself the 'this' type by including an extra type argument - var arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type])); + // (Unless it's provided in the case that the tuple is a type parameter constraint) + var arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type.thisType || type])); var members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo); @@ -20841,24 +20848,27 @@ var ts; return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 141 /* TypeParameter */).parent); } function getTypeListId(types) { + var result = ""; if (types) { - switch (types.length) { - case 1: - return "" + types[0].id; - case 2: - return types[0].id + "," + types[1].id; - default: - var result = ""; - for (var i = 0; i < types.length; i++) { - if (i > 0) { - result += ","; - } - result += types[i].id; - } - return result; + var length_3 = types.length; + var i = 0; + while (i < length_3) { + var startId = types[i].id; + var count = 1; + while (i + count < length_3 && types[i + count].id === startId + count) { + count++; + } + if (result.length) { + result += ","; + } + result += startId; + if (count > 1) { + result += ":" + count; + } + i += count; } } - return ""; + return result; } // This function is used to propagate certain flags when creating new object type references and union types. // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type @@ -20945,8 +20955,9 @@ var ts; case 194 /* ExpressionWithTypeArguments */: // We only support expressions that are simple qualified names. For other // expressions this produces undefined. - if (ts.isSupportedExpressionWithTypeArguments(node)) { - return node.expression; + var expr = node.expression; + if (ts.isEntityNameExpression(expr)) { + return expr; } } return undefined; @@ -20984,14 +20995,14 @@ var ts; var typeReferenceName = getTypeReferenceName(node); symbol = resolveTypeReferenceName(node, typeReferenceName); type = getTypeReferenceType(node, symbol); - links.resolvedSymbol = symbol; - links.resolvedType = type; } else { // We only support expressions that are simple qualified names. For other expressions this produces undefined. - var typeNameOrExpression = node.kind === 155 /* TypeReference */ ? node.typeName : - ts.isSupportedExpressionWithTypeArguments(node) ? node.expression : - undefined; + var typeNameOrExpression = node.kind === 155 /* TypeReference */ + ? node.typeName + : ts.isEntityNameExpression(node.expression) + ? node.expression + : undefined; symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, 793064 /* Type */) || unknownSymbol; type = symbol === unknownSymbol ? unknownType : symbol.flags & (32 /* Class */ | 64 /* Interface */) ? getTypeFromClassOrInterfaceReference(node, symbol) : @@ -21096,14 +21107,15 @@ var ts; } return links.resolvedType; } - function createTupleType(elementTypes) { - var id = getTypeListId(elementTypes); - return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes)); + function createTupleType(elementTypes, thisType) { + var id = getTypeListId(elementTypes) + "," + (thisType ? thisType.id : 0); + return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType)); } - function createNewTupleType(elementTypes) { + function createNewTupleType(elementTypes, thisType) { var propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0); var type = createObjectType(262144 /* Tuple */ | propagatedFlags); type.elementTypes = elementTypes; + type.thisType = thisType; return type; } function getTypeFromTupleTypeNode(node) { @@ -31181,7 +31193,7 @@ var ts; if (implementedTypeNodes) { for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) { var typeRefNode = implementedTypeNodes_1[_b]; - if (!ts.isSupportedExpressionWithTypeArguments(typeRefNode)) { + if (!ts.isEntityNameExpression(typeRefNode.expression)) { error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(typeRefNode); @@ -31396,7 +31408,7 @@ var ts; checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { - if (!ts.isSupportedExpressionWithTypeArguments(heritageElement)) { + if (!ts.isEntityNameExpression(heritageElement.expression)) { error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(heritageElement); @@ -31822,19 +31834,20 @@ var ts; } } function getFirstIdentifier(node) { - while (true) { - if (node.kind === 139 /* QualifiedName */) { - node = node.left; - } - else if (node.kind === 172 /* PropertyAccessExpression */) { - node = node.expression; - } - else { - break; - } + switch (node.kind) { + case 69 /* Identifier */: + return node; + case 139 /* QualifiedName */: + do { + node = node.left; + } while (node.kind !== 69 /* Identifier */); + return node; + case 172 /* PropertyAccessExpression */: + do { + node = node.expression; + } while (node.kind !== 69 /* Identifier */); + return node; } - ts.Debug.assert(node.kind === 69 /* Identifier */); - return node; } function checkExternalImportOrExportDeclaration(node) { var moduleName = ts.getExternalModuleName(node); @@ -32479,17 +32492,15 @@ var ts; default: } } - if (entityName.parent.kind === 235 /* ExportAssignment */) { + if (entityName.parent.kind === 235 /* ExportAssignment */ && ts.isEntityNameExpression(entityName)) { return resolveEntityName(entityName, /*all meanings*/ 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 8388608 /* Alias */); } - if (entityName.kind !== 172 /* PropertyAccessExpression */) { - if (isInRightSideOfImportOrExportAssignment(entityName)) { - // Since we already checked for ExportAssignment, this really could only be an Import - var importEqualsDeclaration = ts.getAncestor(entityName, 229 /* ImportEqualsDeclaration */); - ts.Debug.assert(importEqualsDeclaration !== undefined); - return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); - } + if (entityName.kind !== 172 /* PropertyAccessExpression */ && isInRightSideOfImportOrExportAssignment(entityName)) { + // Since we already checked for ExportAssignment, this really could only be an Import + var importEqualsDeclaration = ts.getAncestor(entityName, 229 /* ImportEqualsDeclaration */); + ts.Debug.assert(importEqualsDeclaration !== undefined); + return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); } if (ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { entityName = entityName.parent; @@ -35821,7 +35832,7 @@ var ts; writeEntityName(entityName); } function emitExpressionWithTypeArguments(node) { - if (ts.isSupportedExpressionWithTypeArguments(node)) { + if (ts.isEntityNameExpression(node.expression)) { ts.Debug.assert(node.expression.kind === 69 /* Identifier */ || node.expression.kind === 172 /* PropertyAccessExpression */); emitEntityName(node.expression); if (node.typeArguments) { @@ -36335,7 +36346,7 @@ var ts; emitCommaList(typeReferences, emitTypeOfTypeReference); } function emitTypeOfTypeReference(node) { - if (ts.isSupportedExpressionWithTypeArguments(node)) { + if (ts.isEntityNameExpression(node.expression)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } else if (!isImplementsList && node.expression.kind === 93 /* NullKeyword */) { @@ -46905,9 +46916,9 @@ var ts; function reportDiagnosticWithColorAndContext(diagnostic, host) { var output = ""; if (diagnostic.file) { - var start = diagnostic.start, length_3 = diagnostic.length, file = diagnostic.file; + var start = diagnostic.start, length_4 = diagnostic.length, file = diagnostic.file; var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character; - var _b = ts.getLineAndCharacterOfPosition(file, start + length_3), lastLine = _b.line, lastLineChar = _b.character; + var _b = ts.getLineAndCharacterOfPosition(file, start + length_4), lastLine = _b.line, lastLineChar = _b.character; var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line; var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName; var hasMoreThanFiveLines = (lastLine - firstLine) >= 4; @@ -60104,7 +60115,7 @@ var ts; var lastEnd = 0; for (var i = 0, n = dense.length; i < n; i += 3) { var start = dense[i]; - var length_4 = dense[i + 1]; + var length_5 = dense[i + 1]; var type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { @@ -60113,8 +60124,8 @@ var ts; entries.push({ length: whitespaceLength_1, classification: TokenClass.Whitespace }); } } - entries.push({ length: length_4, classification: convertClassification(type) }); - lastEnd = start + length_4; + entries.push({ length: length_5, classification: convertClassification(type) }); + lastEnd = start + length_5; } var whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { diff --git a/kicktravis b/kicktravis index e1d80bb..352dcc1 100644 --- a/kicktravis +++ b/kicktravis @@ -1 +1 @@ -2016-08-11 [ci skip] Version: 1.201608110010.1+e16326de8b910926f95bcf9f16aed0db5265d1fb +2016-08-12 [ci skip] Version: 1.201608120008.1+9ac13abfd196f662ce606d8d99cb8791c2ad61fe diff --git a/package.json b/package.json index f8851fb..3bacb43 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ntypescript", - "version": "1.201608110010.1+e16326de8b910926f95bcf9f16aed0db5265d1fb", + "version": "1.201608120008.1+9ac13abfd196f662ce606d8d99cb8791c2ad61fe", "description": "A nicer version of microsoft/typescript packaged and released for API developers", "main": "./bin/ntypescript.js", "bin": { diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8d8666a..502cb39 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1887,18 +1887,17 @@ namespace ts { } function bindExportAssignment(node: ExportAssignment | BinaryExpression) { - const boundExpression = node.kind === SyntaxKind.ExportAssignment ? (node).expression : (node).right; if (!container.symbol || !container.symbol.exports) { // Export assignment in some sort of block construct bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)); } - else if (boundExpression.kind === SyntaxKind.Identifier && node.kind === SyntaxKind.ExportAssignment) { - // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); - } else { - // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); + const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) + // An export default clause with an EntityNameExpression exports all meanings of that identifier + ? SymbolFlags.Alias + // An export default clause with any other expression exports a value + : SymbolFlags.Property; + declareSymbol(container.symbol.exports, container.symbol, node, flags, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c88ab16..43ec22d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -664,7 +664,7 @@ namespace ts { // Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and // the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with // the given name can be found. - function resolveName(location: Node, name: string, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage, nameArg: string | Identifier): Symbol { + function resolveName(location: Node | undefined, name: string, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage, nameArg: string | Identifier): Symbol { let result: Symbol; let lastLocation: Node; let propertyWithInvalidInitializer: Node; @@ -881,7 +881,8 @@ namespace ts { if (!result) { if (nameNotFoundMessage) { - if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && + if (!errorLocation || + !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && !checkAndReportErrorForExtendingInterface(errorLocation)) { error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg)); } @@ -930,7 +931,7 @@ namespace ts { } function checkAndReportErrorForMissingPrefix(errorLocation: Node, name: string, nameArg: string | Identifier): boolean { - if (!errorLocation || (errorLocation.kind === SyntaxKind.Identifier && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) { + if ((errorLocation.kind === SyntaxKind.Identifier && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) { return false; } @@ -968,28 +969,30 @@ namespace ts { function checkAndReportErrorForExtendingInterface(errorLocation: Node): boolean { - let parentClassExpression = errorLocation; - while (parentClassExpression) { - const kind = parentClassExpression.kind; - if (kind === SyntaxKind.Identifier || kind === SyntaxKind.PropertyAccessExpression) { - parentClassExpression = parentClassExpression.parent; - continue; - } - if (kind === SyntaxKind.ExpressionWithTypeArguments) { - break; - } - return false; - } - if (!parentClassExpression) { - return false; - } - const expression = (parentClassExpression).expression; - if (resolveEntityName(expression, SymbolFlags.Interface, /*ignoreErrors*/ true)) { + const expression = getEntityNameForExtendingInterface(errorLocation); + const isError = !!(expression && resolveEntityName(expression, SymbolFlags.Interface, /*ignoreErrors*/ true)); + if (isError) { error(errorLocation, Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, getTextOfNode(expression)); - return true; } - return false; + return isError; } + /** + * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression, + * but returns undefined if that expression is not an EntityNameExpression. + */ + function getEntityNameForExtendingInterface(node: Node): EntityNameExpression | undefined { + switch (node.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.PropertyAccessExpression: + return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined; + case SyntaxKind.ExpressionWithTypeArguments: + Debug.assert(isEntityNameExpression((node).expression)); + return (node).expression; + default: + return undefined; + } + } + function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void { Debug.assert((result.flags & SymbolFlags.BlockScopedVariable) !== 0); @@ -1033,7 +1036,7 @@ namespace ts { } function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration { - return forEach(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined); + return find(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined); } function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol { @@ -1168,7 +1171,7 @@ namespace ts { } function getTargetOfExportAssignment(node: ExportAssignment): Symbol { - return resolveEntityName(node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace); + return resolveEntityName(node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace); } function getTargetOfAliasDeclaration(node: Declaration): Symbol { @@ -1278,7 +1281,7 @@ namespace ts { } // Resolves a qualified name and any involved aliases - function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean): Symbol { + function resolveEntityName(name: EntityNameOrEntityNameExpression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean): Symbol | undefined { if (nodeIsMissing(name)) { return undefined; } @@ -1293,7 +1296,7 @@ namespace ts { } } else if (name.kind === SyntaxKind.QualifiedName || name.kind === SyntaxKind.PropertyAccessExpression) { - const left = name.kind === SyntaxKind.QualifiedName ? (name).left : (name).expression; + const left = name.kind === SyntaxKind.QualifiedName ? (name).left : (name).expression; const right = name.kind === SyntaxKind.QualifiedName ? (name).right : (name).name; const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors); @@ -1538,8 +1541,8 @@ namespace ts { function createType(flags: TypeFlags): Type { const result = new Type(checker, flags); - result.id = typeCount; typeCount++; + result.id = typeCount; return result; } @@ -1849,7 +1852,7 @@ namespace ts { } } - function isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult { + function isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult { // get symbol of the first identifier of the entityName let meaning: SymbolFlags; if (entityName.parent.kind === SyntaxKind.TypeQuery || isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) { @@ -3679,7 +3682,7 @@ namespace ts { const baseTypeNodes = getInterfaceBaseTypeNodes(declaration); if (baseTypeNodes) { for (const node of baseTypeNodes) { - if (isSupportedExpressionWithTypeArguments(node)) { + if (isEntityNameExpression(node.expression)) { const baseSymbol = resolveEntityName(node.expression, SymbolFlags.Type, /*ignoreErrors*/ true); if (!baseSymbol || !(baseSymbol.flags & SymbolFlags.Interface) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) { return false; @@ -4000,6 +4003,9 @@ namespace ts { return createTypeReference((type).target, concatenate((type).typeArguments, [thisArgument || (type).target.thisType])); } + if (type.flags & TypeFlags.Tuple) { + return createTupleType((type as TupleType).elementTypes, thisArgument); + } return type; } @@ -4103,7 +4109,8 @@ namespace ts { function resolveTupleTypeMembers(type: TupleType) { const arrayElementType = getUnionType(type.elementTypes); // Make the tuple type itself the 'this' type by including an extra type argument - const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type])); + // (Unless it's provided in the case that the tuple is a type parameter constraint) + const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type.thisType || type])); const members = createTupleTypeMemberSymbols(type.elementTypes); addInheritedMembers(members, arrayType.properties); setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo); @@ -4941,24 +4948,27 @@ namespace ts { } function getTypeListId(types: Type[]) { + let result = ""; if (types) { - switch (types.length) { - case 1: - return "" + types[0].id; - case 2: - return types[0].id + "," + types[1].id; - default: - let result = ""; - for (let i = 0; i < types.length; i++) { - if (i > 0) { - result += ","; - } - result += types[i].id; - } - return result; + const length = types.length; + let i = 0; + while (i < length) { + const startId = types[i].id; + let count = 1; + while (i + count < length && types[i + count].id === startId + count) { + count++; + } + if (result.length) { + result += ","; + } + result += startId; + if (count > 1) { + result += ":" + count; + } + i += count; } } - return ""; + return result; } // This function is used to propagate certain flags when creating new object type references and union types. @@ -5041,7 +5051,7 @@ namespace ts { return getDeclaredTypeOfSymbol(symbol); } - function getTypeReferenceName(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): LeftHandSideExpression | EntityName { + function getTypeReferenceName(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): EntityNameOrEntityNameExpression | undefined { switch (node.kind) { case SyntaxKind.TypeReference: return (node).typeName; @@ -5050,8 +5060,9 @@ namespace ts { case SyntaxKind.ExpressionWithTypeArguments: // We only support expressions that are simple qualified names. For other // expressions this produces undefined. - if (isSupportedExpressionWithTypeArguments(node)) { - return (node).expression; + const expr = (node).expression; + if (isEntityNameExpression(expr)) { + return expr; } // fall through; @@ -5062,7 +5073,7 @@ namespace ts { function resolveTypeReferenceName( node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, - typeReferenceName: LeftHandSideExpression | EntityName) { + typeReferenceName: EntityNameExpression | EntityName) { if (!typeReferenceName) { return unknownSymbol; @@ -5103,15 +5114,14 @@ namespace ts { const typeReferenceName = getTypeReferenceName(node); symbol = resolveTypeReferenceName(node, typeReferenceName); type = getTypeReferenceType(node, symbol); - - links.resolvedSymbol = symbol; - links.resolvedType = type; } else { // We only support expressions that are simple qualified names. For other expressions this produces undefined. - const typeNameOrExpression = node.kind === SyntaxKind.TypeReference ? (node).typeName : - isSupportedExpressionWithTypeArguments(node) ? (node).expression : - undefined; + const typeNameOrExpression: EntityNameOrEntityNameExpression = node.kind === SyntaxKind.TypeReference + ? (node).typeName + : isEntityNameExpression((node).expression) + ? (node).expression + : undefined; symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol; type = symbol === unknownSymbol ? unknownType : symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) : @@ -5230,15 +5240,16 @@ namespace ts { return links.resolvedType; } - function createTupleType(elementTypes: Type[]) { - const id = getTypeListId(elementTypes); - return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes)); + function createTupleType(elementTypes: Type[], thisType?: Type) { + const id = getTypeListId(elementTypes) + "," + (thisType ? thisType.id : 0); + return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType)); } - function createNewTupleType(elementTypes: Type[]) { + function createNewTupleType(elementTypes: Type[], thisType?: Type) { const propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0); const type = createObjectType(TypeFlags.Tuple | propagatedFlags); type.elementTypes = elementTypes; + type.thisType = thisType; return type; } @@ -16382,7 +16393,7 @@ namespace ts { const implementedTypeNodes = getClassImplementsHeritageClauseElements(node); if (implementedTypeNodes) { for (const typeRefNode of implementedTypeNodes) { - if (!isSupportedExpressionWithTypeArguments(typeRefNode)) { + if (!isEntityNameExpression(typeRefNode.expression)) { error(typeRefNode.expression, Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(typeRefNode); @@ -16624,7 +16635,7 @@ namespace ts { checkObjectTypeForDuplicateDeclarations(node); } forEach(getInterfaceBaseTypeNodes(node), heritageElement => { - if (!isSupportedExpressionWithTypeArguments(heritageElement)) { + if (!isEntityNameExpression(heritageElement.expression)) { error(heritageElement.expression, Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(heritageElement); @@ -17089,20 +17100,21 @@ namespace ts { } } - function getFirstIdentifier(node: EntityName | Expression): Identifier { - while (true) { - if (node.kind === SyntaxKind.QualifiedName) { - node = (node).left; - } - else if (node.kind === SyntaxKind.PropertyAccessExpression) { - node = (node).expression; - } - else { - break; - } + function getFirstIdentifier(node: EntityNameOrEntityNameExpression): Identifier { + switch (node.kind) { + case SyntaxKind.Identifier: + return node; + case SyntaxKind.QualifiedName: + do { + node = (node).left; + } while (node.kind !== SyntaxKind.Identifier); + return node; + case SyntaxKind.PropertyAccessExpression: + do { + node = (node).expression; + } while (node.kind !== SyntaxKind.Identifier); + return node; } - Debug.assert(node.kind === SyntaxKind.Identifier); - return node; } function checkExternalImportOrExportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): boolean { @@ -17801,7 +17813,7 @@ namespace ts { return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined; } - function getSymbolOfEntityNameOrPropertyAccessExpression(entityName: EntityName | PropertyAccessExpression): Symbol { + function getSymbolOfEntityNameOrPropertyAccessExpression(entityName: EntityName | PropertyAccessExpression): Symbol | undefined { if (isDeclarationName(entityName)) { return getSymbolOfNode(entityName.parent); } @@ -17820,22 +17832,20 @@ namespace ts { } } - if (entityName.parent.kind === SyntaxKind.ExportAssignment) { - return resolveEntityName(entityName, + if (entityName.parent.kind === SyntaxKind.ExportAssignment && isEntityNameExpression(entityName)) { + return resolveEntityName(entityName, /*all meanings*/ SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); } - if (entityName.kind !== SyntaxKind.PropertyAccessExpression) { - if (isInRightSideOfImportOrExportAssignment(entityName)) { - // Since we already checked for ExportAssignment, this really could only be an Import - const importEqualsDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); - Debug.assert(importEqualsDeclaration !== undefined); - return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); - } + if (entityName.kind !== SyntaxKind.PropertyAccessExpression && isInRightSideOfImportOrExportAssignment(entityName)) { + // Since we already checked for ExportAssignment, this really could only be an Import + const importEqualsDeclaration = getAncestor(entityName, SyntaxKind.ImportEqualsDeclaration); + Debug.assert(importEqualsDeclaration !== undefined); + return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importEqualsDeclaration, /*dontResolveAlias*/ true); } if (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { - entityName = entityName.parent; + entityName = entityName.parent; } if (isHeritageClauseElementIdentifier(entityName)) { @@ -18548,7 +18558,7 @@ namespace ts { }; // defined here to avoid outer scope pollution - function getTypeReferenceDirectivesForEntityName(node: EntityName | PropertyAccessExpression): string[] { + function getTypeReferenceDirectivesForEntityName(node: EntityNameOrEntityNameExpression): string[] { // program does not have any files with type reference directives - bail out if (!fileToDirective) { return undefined; diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6c87ad8..5494101 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -81,7 +81,7 @@ namespace ts { * returns a truthy value, then returns that value. * If no such value is found, the callback is applied to each element of array and undefined is returned. */ - export function forEach(array: T[], callback: (element: T, index: number) => U): U { + export function forEach(array: T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined { if (array) { for (let i = 0, len = array.length; i < len; i++) { const result = callback(array[i], i); @@ -93,6 +93,17 @@ namespace ts { return undefined; } + /** Like `forEach`, but assumes existence of array and fails if no truthy value is found. */ + export function find(array: T[], callback: (element: T, index: number) => U | undefined): U { + for (let i = 0, len = array.length; i < len; i++) { + const result = callback(array[i], i); + if (result) { + return result; + } + } + Debug.fail(); + } + export function contains(array: T[], value: T): boolean { if (array) { for (const v of array) { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index d93a8a0..c93784c 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -441,7 +441,7 @@ namespace ts { } } - function emitEntityName(entityName: EntityName | PropertyAccessExpression) { + function emitEntityName(entityName: EntityNameOrEntityNameExpression) { const visibilityResult = resolver.isEntityNameVisible(entityName, // Aliases can be written asynchronously so use correct enclosing declaration entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration ? entityName.parent : enclosingDeclaration); @@ -452,9 +452,9 @@ namespace ts { } function emitExpressionWithTypeArguments(node: ExpressionWithTypeArguments) { - if (isSupportedExpressionWithTypeArguments(node)) { + if (isEntityNameExpression(node.expression)) { Debug.assert(node.expression.kind === SyntaxKind.Identifier || node.expression.kind === SyntaxKind.PropertyAccessExpression); - emitEntityName(node.expression); + emitEntityName(node.expression); if (node.typeArguments) { write("<"); emitCommaList(node.typeArguments, emitType); @@ -1019,7 +1019,7 @@ namespace ts { } function emitTypeOfTypeReference(node: ExpressionWithTypeArguments) { - if (isSupportedExpressionWithTypeArguments(node)) { + if (isEntityNameExpression(node.expression)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } else if (!isImplementsList && node.expression.kind === SyntaxKind.NullKeyword) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a6e8604..74a47f3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -982,13 +982,19 @@ namespace ts { multiLine?: boolean; } + export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression; + export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression; + // @kind(SyntaxKind.PropertyAccessExpression) export interface PropertyAccessExpression extends MemberExpression, Declaration { expression: LeftHandSideExpression; name: Identifier; } - - export type IdentifierOrPropertyAccess = Identifier | PropertyAccessExpression; + /** Brand for a PropertyAccessExpression which, like a QualifiedName, consists of a sequence of identifiers separated by dots. */ + export interface PropertyAccessEntityNameExpression extends PropertyAccessExpression { + _propertyAccessExpressionLikeQualifiedNameBrand?: any; + expression: EntityNameExpression; + } // @kind(SyntaxKind.ElementAccessExpression) export interface ElementAccessExpression extends MemberExpression { @@ -2031,7 +2037,7 @@ namespace ts { writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult; - isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult; + isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; getReferencedValueDeclaration(reference: Identifier): Declaration; @@ -2040,7 +2046,7 @@ namespace ts { moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean; isArgumentsLocalBinding(node: Identifier): boolean; getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration): SourceFile; - getTypeReferenceDirectivesForEntityName(name: EntityName | PropertyAccessExpression): string[]; + getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[]; getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[]; } @@ -2371,6 +2377,7 @@ namespace ts { export interface TupleType extends ObjectType { elementTypes: Type[]; // Element types + thisType?: Type; // This-type of tuple (only needed for tuples that are constraints of type parameters) } export interface UnionOrIntersectionType extends Type { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2cfaf1f..df9f4f9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1033,14 +1033,14 @@ namespace ts { && (node).expression.kind === SyntaxKind.SuperKeyword; } - - export function getEntityNameFromTypeNode(node: TypeNode): EntityName | Expression { + export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression { if (node) { switch (node.kind) { case SyntaxKind.TypeReference: return (node).typeName; case SyntaxKind.ExpressionWithTypeArguments: - return (node).expression; + Debug.assert(isEntityNameExpression((node).expression)); + return (node).expression; case SyntaxKind.Identifier: case SyntaxKind.QualifiedName: return (node); @@ -1694,8 +1694,8 @@ namespace ts { // import * as from ... // import { x as } from ... // export { x as } from ... - // export = ... - // export default ... + // export = + // export default export function isAliasSymbolDeclaration(node: Node): boolean { return node.kind === SyntaxKind.ImportEqualsDeclaration || node.kind === SyntaxKind.NamespaceExportDeclaration || @@ -1703,7 +1703,11 @@ namespace ts { node.kind === SyntaxKind.NamespaceImport || node.kind === SyntaxKind.ImportSpecifier || node.kind === SyntaxKind.ExportSpecifier || - node.kind === SyntaxKind.ExportAssignment && (node).expression.kind === SyntaxKind.Identifier; + node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node); + } + + export function exportAssignmentIsAlias(node: ExportAssignment): boolean { + return isEntityNameExpression(node.expression); } export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration) { @@ -2681,22 +2685,9 @@ namespace ts { isClassLike(node.parent.parent); } - // Returns false if this heritage clause element's expression contains something unsupported - // (i.e. not a name or dotted name). - export function isSupportedExpressionWithTypeArguments(node: ExpressionWithTypeArguments): boolean { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - - function isSupportedExpressionWithTypeArgumentsRest(node: Expression): boolean { - if (node.kind === SyntaxKind.Identifier) { - return true; - } - else if (isPropertyAccessExpression(node)) { - return isSupportedExpressionWithTypeArgumentsRest(node.expression); - } - else { - return false; - } + export function isEntityNameExpression(node: Expression): node is EntityNameExpression { + return node.kind === SyntaxKind.Identifier || + node.kind === SyntaxKind.PropertyAccessExpression && isEntityNameExpression((node).expression); } export function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) {