diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5df41f62344..f946c05ee70 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -598,7 +598,7 @@ module ts { if (moduleSymbol.flags & SymbolFlags.Variable) { let typeAnnotation = (moduleSymbol.valueDeclaration).type; if (typeAnnotation) { - return getPropertyOfType(getTypeFromTypeNodeOrHeritageClauseElement(typeAnnotation), name); + return getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name); } } } @@ -647,7 +647,7 @@ module ts { if (symbol.flags & SymbolFlags.Variable) { var typeAnnotation = (symbol.valueDeclaration).type; if (typeAnnotation) { - return resolveSymbol(getPropertyOfType(getTypeFromTypeNodeOrHeritageClauseElement(typeAnnotation), name)); + return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name)); } } } @@ -2128,7 +2128,7 @@ module ts { } // Use type from type annotation if one is present if (declaration.type) { - return getTypeFromTypeNodeOrHeritageClauseElement(declaration.type); + return getTypeFromTypeNode(declaration.type); } if (declaration.kind === SyntaxKind.Parameter) { let func = declaration.parent; @@ -2290,18 +2290,18 @@ module ts { return links.type; } - function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode | LiteralExpression { + function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode { return accessor && accessor.parameters.length > 0 && accessor.parameters[0].type; } function getAnnotatedAccessorType(accessor: AccessorDeclaration): Type { if (accessor) { if (accessor.kind === SyntaxKind.GetAccessor) { - return accessor.type && getTypeFromTypeNodeOrHeritageClauseElement(accessor.type); + return accessor.type && getTypeFromTypeNode(accessor.type); } else { let setterTypeAnnotation = getSetAccessorTypeAnnotationNode(accessor); - return setterTypeAnnotation && getTypeFromTypeNodeOrHeritageClauseElement(setterTypeAnnotation); + return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation); } } return undefined; @@ -2542,7 +2542,7 @@ module ts { if (!links.declaredType) { links.declaredType = resolvingType; let declaration = getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration); - let type = getTypeFromTypeNodeOrHeritageClauseElement(declaration.type); + let type = getTypeFromTypeNode(declaration.type); if (links.declaredType === resolvingType) { links.declaredType = type; } @@ -3084,7 +3084,7 @@ module ts { returnType = classType; } else if (declaration.type) { - returnType = getTypeFromTypeNodeOrHeritageClauseElement(declaration.type); + returnType = getTypeFromTypeNode(declaration.type); } else { // TypeScript 1.0 spec (April 2014): @@ -3242,7 +3242,7 @@ module ts { function getIndexTypeOfSymbol(symbol: Symbol, kind: IndexKind): Type { let declaration = getIndexDeclarationOfSymbol(symbol, kind); return declaration - ? declaration.type ? getTypeFromTypeNodeOrHeritageClauseElement(declaration.type) : anyType + ? declaration.type ? getTypeFromTypeNode(declaration.type) : anyType : undefined; } @@ -3253,7 +3253,7 @@ module ts { type.constraint = targetConstraint ? instantiateType(targetConstraint, type.mapper) : noConstraintType; } else { - type.constraint = getTypeFromTypeNodeOrHeritageClauseElement((getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter)).constraint); + type.constraint = getTypeFromTypeNode((getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter)).constraint); } } return type.constraint === noConstraintType ? undefined : type.constraint; @@ -3384,7 +3384,7 @@ module ts { if (type.flags & (TypeFlags.Class | TypeFlags.Interface) && type.flags & TypeFlags.Reference) { let typeParameters = (type).typeParameters; if (node.typeArguments && node.typeArguments.length === typeParameters.length) { - type = createTypeReference(type, map(node.typeArguments, getTypeFromTypeNodeOrHeritageClauseElement)); + type = createTypeReference(type, map(node.typeArguments, getTypeFromTypeNode)); } else { error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), typeParameters.length); @@ -3482,7 +3482,7 @@ module ts { function getTypeFromArrayTypeNode(node: ArrayTypeNode): Type { let links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = createArrayType(getTypeFromTypeNodeOrHeritageClauseElement(node.elementType)); + links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType)); } return links.resolvedType; } @@ -3500,7 +3500,7 @@ module ts { function getTypeFromTupleTypeNode(node: TupleTypeNode): Type { let links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = createTupleType(map(node.elementTypes, getTypeFromTypeNodeOrHeritageClauseElement)); + links.resolvedType = createTupleType(map(node.elementTypes, getTypeFromTypeNode)); } return links.resolvedType; } @@ -3609,7 +3609,7 @@ module ts { function getTypeFromUnionTypeNode(node: UnionTypeNode): Type { let links = getNodeLinks(node); if (!links.resolvedType) { - links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNodeOrHeritageClauseElement), /*noSubtypeReduction*/ true); + links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true); } return links.resolvedType; } @@ -3623,7 +3623,7 @@ module ts { return links.resolvedType; } - function getStringLiteralType(node: LiteralExpression): StringLiteralType { + function getStringLiteralType(node: StringLiteral): StringLiteralType { if (hasProperty(stringLiteralTypes, node.text)) { return stringLiteralTypes[node.text]; } @@ -3633,7 +3633,7 @@ module ts { return type; } - function getTypeFromStringLiteral(node: LiteralExpression): Type { + function getTypeFromStringLiteral(node: StringLiteral): Type { let links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getStringLiteralType(node); @@ -3641,7 +3641,7 @@ module ts { return links.resolvedType; } - function getTypeFromTypeNodeOrHeritageClauseElement(node: TypeNode | LiteralExpression | HeritageClauseElement): Type { + function getTypeFromTypeNode(node: TypeNode): Type { switch (node.kind) { case SyntaxKind.AnyKeyword: return anyType; @@ -3656,7 +3656,7 @@ module ts { case SyntaxKind.VoidKeyword: return voidType; case SyntaxKind.StringLiteral: - return getTypeFromStringLiteral(node); + return getTypeFromStringLiteral(node); case SyntaxKind.TypeReference: return getTypeFromTypeReference(node); case SyntaxKind.HeritageClauseElement: @@ -3670,7 +3670,7 @@ module ts { case SyntaxKind.UnionType: return getTypeFromUnionTypeNode(node); case SyntaxKind.ParenthesizedType: - return getTypeFromTypeNodeOrHeritageClauseElement((node).type); + return getTypeFromTypeNode((node).type); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.TypeLiteral: @@ -5681,7 +5681,7 @@ module ts { let declaration = node.parent; if (node === declaration.initializer) { if (declaration.type) { - return getTypeFromTypeNodeOrHeritageClauseElement(declaration.type); + return getTypeFromTypeNode(declaration.type); } if (declaration.kind === SyntaxKind.Parameter) { let type = getContextuallyTypedParameterType(declaration); @@ -5884,7 +5884,7 @@ module ts { case SyntaxKind.NewExpression: return getContextualTypeForArgument(parent, node); case SyntaxKind.TypeAssertionExpression: - return getTypeFromTypeNodeOrHeritageClauseElement((parent).type); + return getTypeFromTypeNode((parent).type); case SyntaxKind.BinaryExpression: return getContextualTypeForBinaryOperand(node); case SyntaxKind.PropertyAssignment: @@ -6706,7 +6706,7 @@ module ts { let typeArgumentsAreAssignable = true; for (let i = 0; i < typeParameters.length; i++) { let typeArgNode = typeArguments[i]; - let typeArgument = getTypeFromTypeNodeOrHeritageClauseElement(typeArgNode); + let typeArgument = getTypeFromTypeNode(typeArgNode); // Do not push on this array! It has a preallocated length typeArgumentResultTypes[i] = typeArgument; if (typeArgumentsAreAssignable /* so far */) { @@ -6728,9 +6728,12 @@ module ts { let paramType = getTypeAtPosition(signature, i); // A tagged template expression provides a special first argument, and string literals get string literal types // unless we're reporting errors - let argType = i === 0 && node.kind === SyntaxKind.TaggedTemplateExpression ? globalTemplateStringsArrayType : - arg.kind === SyntaxKind.StringLiteral && !reportErrors ? getStringLiteralType(arg) : - checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined); + let argType = i === 0 && node.kind === SyntaxKind.TaggedTemplateExpression + ? globalTemplateStringsArrayType + : arg.kind === SyntaxKind.StringLiteral && !reportErrors + ? getStringLiteralType(arg) + : checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined); + // Use argument expression as error location when reporting errors if (!checkTypeRelatedTo(argType, paramType, relation, reportErrors ? arg : undefined, Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1)) { @@ -7188,7 +7191,7 @@ module ts { function checkTypeAssertion(node: TypeAssertion): Type { let exprType = checkExpression(node.expression); - let targetType = getTypeFromTypeNodeOrHeritageClauseElement(node.type); + let targetType = getTypeFromTypeNode(node.type); if (produceDiagnostics && targetType !== unknownType) { let widenedType = getWidenedType(exprType); if (!(isTypeAssignableTo(targetType, widenedType))) { @@ -7362,7 +7365,7 @@ module ts { function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); if (node.type && !node.asteriskToken) { - checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNodeOrHeritageClauseElement(node.type)); + checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } if (node.body) { @@ -7372,7 +7375,7 @@ module ts { else { let exprType = checkExpression(node.body); if (node.type) { - checkTypeAssignableTo(exprType, getTypeFromTypeNodeOrHeritageClauseElement(node.type), node.body, /*headMessage*/ undefined); + checkTypeAssignableTo(exprType, getTypeFromTypeNode(node.type), node.body, /*headMessage*/ undefined); } checkFunctionExpressionBodies(node.body); } @@ -8801,12 +8804,12 @@ module ts { } /** Checks a type reference node as an expression. */ - function checkTypeNodeAsExpression(node: TypeNode | LiteralExpression) { + function checkTypeNodeAsExpression(node: TypeNode) { // When we are emitting type metadata for decorators, we need to try to check the type // as if it were an expression so that we can emit the type in a value position when we // serialize the type metadata. if (node && node.kind === SyntaxKind.TypeReference) { - let type = getTypeFromTypeNodeOrHeritageClauseElement(node); + let type = getTypeFromTypeNode(node); let shouldCheckIfUnknownType = type === unknownType && compilerOptions.separateCompilation; if (!type || (!shouldCheckIfUnknownType && type.flags & (TypeFlags.Intrinsic | TypeFlags.NumberLike | TypeFlags.StringLike))) { return; @@ -8826,7 +8829,8 @@ module ts { case SyntaxKind.PropertyDeclaration: checkTypeNodeAsExpression((node).type); break; - case SyntaxKind.Parameter: checkTypeNodeAsExpression((node).type); + case SyntaxKind.Parameter: + checkTypeNodeAsExpression((node).type); break; case SyntaxKind.MethodDeclaration: checkTypeNodeAsExpression((node).type); @@ -8942,7 +8946,7 @@ module ts { checkSourceElement(node.body); if (node.type && !isAccessor(node.kind) && !node.asteriskToken) { - checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNodeOrHeritageClauseElement(node.type)); + checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } // Report an implicit any error if there is no body, no explicit return type, and node is not a private method @@ -10106,7 +10110,7 @@ module ts { if (!tp1.constraint || !tp2.constraint) { return false; } - if (!isTypeIdenticalTo(getTypeFromTypeNodeOrHeritageClauseElement(tp1.constraint), getTypeFromTypeNodeOrHeritageClauseElement(tp2.constraint))) { + if (!isTypeIdenticalTo(getTypeFromTypeNode(tp1.constraint), getTypeFromTypeNode(tp2.constraint))) { return false; } } @@ -11137,7 +11141,7 @@ module ts { return node.parent && node.parent.kind === SyntaxKind.HeritageClauseElement; } - function isTypeNodeOrHeritageClauseElement(node: Node): boolean { + function isTypeNode(node: Node): boolean { if (SyntaxKind.FirstTypeNode <= node.kind && node.kind <= SyntaxKind.LastTypeNode) { return true; } @@ -11386,8 +11390,8 @@ module ts { return unknownType; } - if (isTypeNodeOrHeritageClauseElement(node)) { - return getTypeFromTypeNodeOrHeritageClauseElement(node); + if (isTypeNode(node)) { + return getTypeFromTypeNode(node); } if (isExpression(node)) { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 30f50faf562..3f613271ce1 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -258,7 +258,7 @@ module ts { handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning)); } - function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode | StringLiteralExpression, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) { + function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) { writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic; write(": "); if (type) { @@ -314,12 +314,12 @@ module ts { } } - function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type: TypeNode | EntityName | HeritageClauseElement, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) { + function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type: TypeNode | EntityName, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) { writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic; emitType(type); } - function emitType(type: TypeNode | StringLiteralExpression | Identifier | QualifiedName | HeritageClauseElement) { + function emitType(type: TypeNode | Identifier | QualifiedName) { switch (type.kind) { case SyntaxKind.AnyKeyword: case SyntaxKind.StringKeyword: @@ -1126,7 +1126,7 @@ module ts { writeLine(); } - function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode | StringLiteralExpression { + function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode { if (accessor) { return accessor.kind === SyntaxKind.GetAccessor ? accessor.type // Getter - return type diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5fce6df3bd5..99803f94e4d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1803,7 +1803,7 @@ module ts { function parseParameterType(): TypeNode { if (parseOptional(SyntaxKind.ColonToken)) { return token === SyntaxKind.StringLiteral - ? parseLiteralNode(/*internName:*/ true) + ? parseLiteralNode(/*internName:*/ true) : parseType(); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b3d2f7858ea..370ece347a3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -596,7 +596,11 @@ module ts { type: TypeNode; } - export interface StringLiteralTypeNode extends LiteralExpression, TypeNode { } + // Note that a StringLiteral AST node is both an Expression and a TypeNode. The latter is + // because string literals can appear in the type annotation of a parameter node. + export interface StringLiteral extends LiteralExpression, TypeNode { + _stringLiteralBrand: any; + } // Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing. // Consider 'Expression'. Without the brand, 'Expression' is actually no different @@ -689,10 +693,6 @@ module ts { hasExtendedUnicodeEscape?: boolean; } - export interface StringLiteralExpression extends LiteralExpression { - _stringLiteralExpressionBrand: any; - } - export interface TemplateExpression extends PrimaryExpression { head: LiteralExpression; templateSpans: NodeArray; @@ -739,7 +739,7 @@ module ts { arguments: NodeArray; } - export interface HeritageClauseElement extends Node { + export interface HeritageClauseElement extends TypeNode { expression: LeftHandSideExpression; typeArguments?: NodeArray; }