Numeric and boolean literal types
This commit is contained in:
parent
c7dec0ea68
commit
89596cb73b
7 changed files with 170 additions and 115 deletions
|
@ -114,6 +114,8 @@ namespace ts {
|
||||||
const stringType = createIntrinsicType(TypeFlags.String, "string");
|
const stringType = createIntrinsicType(TypeFlags.String, "string");
|
||||||
const numberType = createIntrinsicType(TypeFlags.Number, "number");
|
const numberType = createIntrinsicType(TypeFlags.Number, "number");
|
||||||
const booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean");
|
const booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean");
|
||||||
|
const trueType = createIntrinsicType(TypeFlags.BooleanLiteral, "true");
|
||||||
|
const falseType = createIntrinsicType(TypeFlags.BooleanLiteral, "false");
|
||||||
const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
|
const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
|
||||||
const voidType = createIntrinsicType(TypeFlags.Void, "void");
|
const voidType = createIntrinsicType(TypeFlags.Void, "void");
|
||||||
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
|
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
|
||||||
|
@ -134,8 +136,8 @@ namespace ts {
|
||||||
|
|
||||||
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||||
|
|
||||||
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
|
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||||
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false);
|
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||||
|
|
||||||
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
|
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
|
||||||
|
|
||||||
|
@ -195,7 +197,8 @@ namespace ts {
|
||||||
const tupleTypes: Map<TupleType> = {};
|
const tupleTypes: Map<TupleType> = {};
|
||||||
const unionTypes: Map<UnionType> = {};
|
const unionTypes: Map<UnionType> = {};
|
||||||
const intersectionTypes: Map<IntersectionType> = {};
|
const intersectionTypes: Map<IntersectionType> = {};
|
||||||
const stringLiteralTypes: Map<StringLiteralType> = {};
|
const stringLiteralTypes: Map<LiteralType> = {};
|
||||||
|
const numericLiteralTypes: Map<LiteralType> = {};
|
||||||
|
|
||||||
const resolutionTargets: TypeSystemEntity[] = [];
|
const resolutionTargets: TypeSystemEntity[] = [];
|
||||||
const resolutionResults: boolean[] = [];
|
const resolutionResults: boolean[] = [];
|
||||||
|
@ -2060,7 +2063,10 @@ namespace ts {
|
||||||
writeAnonymousType(<ObjectType>type, flags);
|
writeAnonymousType(<ObjectType>type, flags);
|
||||||
}
|
}
|
||||||
else if (type.flags & TypeFlags.StringLiteral) {
|
else if (type.flags & TypeFlags.StringLiteral) {
|
||||||
writer.writeStringLiteral(`"${escapeString((<StringLiteralType>type).text)}"`);
|
writer.writeStringLiteral(`"${escapeString((<LiteralType>type).text)}"`);
|
||||||
|
}
|
||||||
|
else if (type.flags & TypeFlags.NumberLiteral) {
|
||||||
|
writer.writeStringLiteral((<LiteralType>type).text);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Should never get here
|
// Should never get here
|
||||||
|
@ -3718,7 +3724,7 @@ namespace ts {
|
||||||
case SyntaxKind.UndefinedKeyword:
|
case SyntaxKind.UndefinedKeyword:
|
||||||
case SyntaxKind.NullKeyword:
|
case SyntaxKind.NullKeyword:
|
||||||
case SyntaxKind.NeverKeyword:
|
case SyntaxKind.NeverKeyword:
|
||||||
case SyntaxKind.StringLiteralType:
|
case SyntaxKind.LiteralType:
|
||||||
return true;
|
return true;
|
||||||
case SyntaxKind.ArrayType:
|
case SyntaxKind.ArrayType:
|
||||||
return isIndependentType((<ArrayTypeNode>node).elementType);
|
return isIndependentType((<ArrayTypeNode>node).elementType);
|
||||||
|
@ -3863,7 +3869,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisType: Type, parameters: Symbol[],
|
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisType: Type, parameters: Symbol[],
|
||||||
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature {
|
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature {
|
||||||
const sig = new Signature(checker);
|
const sig = new Signature(checker);
|
||||||
sig.declaration = declaration;
|
sig.declaration = declaration;
|
||||||
sig.typeParameters = typeParameters;
|
sig.typeParameters = typeParameters;
|
||||||
|
@ -3873,20 +3879,20 @@ namespace ts {
|
||||||
sig.typePredicate = typePredicate;
|
sig.typePredicate = typePredicate;
|
||||||
sig.minArgumentCount = minArgumentCount;
|
sig.minArgumentCount = minArgumentCount;
|
||||||
sig.hasRestParameter = hasRestParameter;
|
sig.hasRestParameter = hasRestParameter;
|
||||||
sig.hasStringLiterals = hasStringLiterals;
|
sig.hasLiteralTypes = hasLiteralTypes;
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneSignature(sig: Signature): Signature {
|
function cloneSignature(sig: Signature): Signature {
|
||||||
return createSignature(sig.declaration, sig.typeParameters, sig.thisType, sig.parameters, sig.resolvedReturnType,
|
return createSignature(sig.declaration, sig.typeParameters, sig.thisType, sig.parameters, sig.resolvedReturnType,
|
||||||
sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals);
|
sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
|
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
|
||||||
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
|
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
|
||||||
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
|
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
|
||||||
if (baseSignatures.length === 0) {
|
if (baseSignatures.length === 0) {
|
||||||
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)];
|
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
|
||||||
}
|
}
|
||||||
const baseTypeNode = getBaseTypeNodeOfClass(classType);
|
const baseTypeNode = getBaseTypeNodeOfClass(classType);
|
||||||
const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode);
|
const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode);
|
||||||
|
@ -4184,7 +4190,7 @@ namespace ts {
|
||||||
else if (type.flags & TypeFlags.NumberLike) {
|
else if (type.flags & TypeFlags.NumberLike) {
|
||||||
type = globalNumberType;
|
type = globalNumberType;
|
||||||
}
|
}
|
||||||
else if (type.flags & TypeFlags.Boolean) {
|
else if (type.flags & TypeFlags.BooleanLike) {
|
||||||
type = globalBooleanType;
|
type = globalBooleanType;
|
||||||
}
|
}
|
||||||
else if (type.flags & TypeFlags.ESSymbol) {
|
else if (type.flags & TypeFlags.ESSymbol) {
|
||||||
|
@ -4426,7 +4432,7 @@ namespace ts {
|
||||||
const links = getNodeLinks(declaration);
|
const links = getNodeLinks(declaration);
|
||||||
if (!links.resolvedSignature) {
|
if (!links.resolvedSignature) {
|
||||||
const parameters: Symbol[] = [];
|
const parameters: Symbol[] = [];
|
||||||
let hasStringLiterals = false;
|
let hasLiteralTypes = false;
|
||||||
let minArgumentCount = -1;
|
let minArgumentCount = -1;
|
||||||
let thisType: Type = undefined;
|
let thisType: Type = undefined;
|
||||||
let hasThisParameter: boolean;
|
let hasThisParameter: boolean;
|
||||||
|
@ -4452,8 +4458,8 @@ namespace ts {
|
||||||
parameters.push(paramSymbol);
|
parameters.push(paramSymbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.type && param.type.kind === SyntaxKind.StringLiteralType) {
|
if (param.type && param.type.kind === SyntaxKind.LiteralType) {
|
||||||
hasStringLiterals = true;
|
hasLiteralTypes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.initializer || param.questionToken || param.dotDotDotToken) {
|
if (param.initializer || param.questionToken || param.dotDotDotToken) {
|
||||||
|
@ -4494,7 +4500,7 @@ namespace ts {
|
||||||
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
|
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
|
||||||
undefined;
|
undefined;
|
||||||
|
|
||||||
links.resolvedSignature = createSignature(declaration, typeParameters, thisType, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
|
links.resolvedSignature = createSignature(declaration, typeParameters, thisType, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasLiteralTypes);
|
||||||
}
|
}
|
||||||
return links.resolvedSignature;
|
return links.resolvedSignature;
|
||||||
}
|
}
|
||||||
|
@ -5182,19 +5188,53 @@ namespace ts {
|
||||||
return links.resolvedType;
|
return links.resolvedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringLiteralTypeForText(text: string): StringLiteralType {
|
function getStringLiteralTypeForText(text: string): LiteralType {
|
||||||
if (hasProperty(stringLiteralTypes, text)) {
|
if (hasProperty(stringLiteralTypes, text)) {
|
||||||
return stringLiteralTypes[text];
|
return stringLiteralTypes[text];
|
||||||
}
|
}
|
||||||
const type = stringLiteralTypes[text] = <StringLiteralType>createType(TypeFlags.StringLiteral);
|
const type = stringLiteralTypes[text] = <LiteralType>createType(TypeFlags.StringLiteral);
|
||||||
type.text = text;
|
type.text = text;
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeFromStringLiteralTypeNode(node: StringLiteralTypeNode): Type {
|
function createLiteralType(flags: TypeFlags, text: string) {
|
||||||
|
const type = <LiteralType>createType(flags);
|
||||||
|
type.text = text;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLiteralTypeForText(flags: TypeFlags, text: string) {
|
||||||
|
const map = flags & TypeFlags.StringLiteral ? stringLiteralTypes : numericLiteralTypes;
|
||||||
|
return hasProperty(map, text) ? map[text] : map[text] = createLiteralType(flags, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTypeFromLiteralExpression(node: Expression): Type {
|
||||||
|
switch (node.kind) {
|
||||||
|
case SyntaxKind.StringLiteral:
|
||||||
|
return getLiteralTypeForText(TypeFlags.StringLiteral, (<LiteralExpression>node).text);
|
||||||
|
case SyntaxKind.NumericLiteral:
|
||||||
|
return getLiteralTypeForText(TypeFlags.NumberLiteral, (<LiteralExpression>node).text);
|
||||||
|
case SyntaxKind.TrueKeyword:
|
||||||
|
return trueType;
|
||||||
|
case SyntaxKind.FalseKeyword:
|
||||||
|
return falseType;
|
||||||
|
case SyntaxKind.PrefixUnaryExpression:
|
||||||
|
if ((<PrefixUnaryExpression>node).operator === SyntaxKind.MinusToken &&
|
||||||
|
(<PrefixUnaryExpression>node).operand.kind === SyntaxKind.NumericLiteral) {
|
||||||
|
return getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>(<PrefixUnaryExpression>node).operand).text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTypeOfLiteralOrExpression(node: Expression): Type {
|
||||||
|
return getTypeFromLiteralExpression(node) || checkExpression(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type {
|
||||||
const links = getNodeLinks(node);
|
const links = getNodeLinks(node);
|
||||||
if (!links.resolvedType) {
|
if (!links.resolvedType) {
|
||||||
links.resolvedType = getStringLiteralTypeForText(unescapeIdentifier(node.text));
|
links.resolvedType = getTypeFromLiteralExpression(node.literal);
|
||||||
}
|
}
|
||||||
return links.resolvedType;
|
return links.resolvedType;
|
||||||
}
|
}
|
||||||
|
@ -5263,8 +5303,8 @@ namespace ts {
|
||||||
case SyntaxKind.ThisType:
|
case SyntaxKind.ThisType:
|
||||||
case SyntaxKind.ThisKeyword:
|
case SyntaxKind.ThisKeyword:
|
||||||
return getTypeFromThisTypeNode(node);
|
return getTypeFromThisTypeNode(node);
|
||||||
case SyntaxKind.StringLiteralType:
|
case SyntaxKind.LiteralType:
|
||||||
return getTypeFromStringLiteralTypeNode(<StringLiteralTypeNode>node);
|
return getTypeFromLiteralTypeNode(<LiteralTypeNode>node);
|
||||||
case SyntaxKind.TypeReference:
|
case SyntaxKind.TypeReference:
|
||||||
case SyntaxKind.JSDocTypeReference:
|
case SyntaxKind.JSDocTypeReference:
|
||||||
return getTypeFromTypeReference(<TypeReferenceNode>node);
|
return getTypeFromTypeReference(<TypeReferenceNode>node);
|
||||||
|
@ -5431,7 +5471,7 @@ namespace ts {
|
||||||
instantiateList(signature.parameters, mapper, instantiateSymbol),
|
instantiateList(signature.parameters, mapper, instantiateSymbol),
|
||||||
instantiateType(signature.resolvedReturnType, mapper),
|
instantiateType(signature.resolvedReturnType, mapper),
|
||||||
freshTypePredicate,
|
freshTypePredicate,
|
||||||
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
|
signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
|
||||||
result.target = signature;
|
result.target = signature;
|
||||||
result.mapper = mapper;
|
result.mapper = mapper;
|
||||||
return result;
|
return result;
|
||||||
|
@ -5918,18 +5958,18 @@ namespace ts {
|
||||||
if (source.flags & TypeFlags.Null) {
|
if (source.flags & TypeFlags.Null) {
|
||||||
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
|
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
|
||||||
}
|
}
|
||||||
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
|
if (source.flags & TypeFlags.NumberLike && target === numberType) return Ternary.True;
|
||||||
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) {
|
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) {
|
||||||
if (result = enumRelatedTo(source, target, reportErrors)) {
|
if (result = enumRelatedTo(source, target, reportErrors)) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
|
if (source.flags & TypeFlags.StringLike && target === stringType) return Ternary.True;
|
||||||
if (relation === assignableRelation || relation === comparableRelation) {
|
if (relation === assignableRelation || relation === comparableRelation) {
|
||||||
if (source.flags & TypeFlags.Any) return Ternary.True;
|
if (source.flags & TypeFlags.Any) return Ternary.True;
|
||||||
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
|
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
|
||||||
}
|
}
|
||||||
if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean) {
|
if (source.flags & TypeFlags.BooleanLike && target.flags & TypeFlags.Boolean) {
|
||||||
return Ternary.True;
|
return Ternary.True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6834,9 +6874,9 @@ namespace ts {
|
||||||
return !!getPropertyOfType(type, "0");
|
return !!getPropertyOfType(type, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
function isStringLiteralUnionType(type: Type): boolean {
|
function isLiteralUnionType(type: Type): boolean {
|
||||||
return type.flags & TypeFlags.StringLiteral ? true :
|
return type.flags & TypeFlags.Literal ? true :
|
||||||
type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isStringLiteralUnionType) :
|
type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isLiteralUnionType) :
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7528,7 +7568,7 @@ namespace ts {
|
||||||
if (flags & TypeFlags.NumberLike) {
|
if (flags & TypeFlags.NumberLike) {
|
||||||
return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts;
|
return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts;
|
||||||
}
|
}
|
||||||
if (flags & TypeFlags.Boolean) {
|
if (flags & TypeFlags.BooleanLike) {
|
||||||
return strictNullChecks ? TypeFacts.BooleanStrictFacts : TypeFacts.BooleanFacts;
|
return strictNullChecks ? TypeFacts.BooleanStrictFacts : TypeFacts.BooleanFacts;
|
||||||
}
|
}
|
||||||
if (flags & TypeFlags.ObjectType) {
|
if (flags & TypeFlags.ObjectType) {
|
||||||
|
@ -7703,11 +7743,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
|
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
|
||||||
if (clause.kind === SyntaxKind.CaseClause) {
|
return clause.kind === SyntaxKind.CaseClause ? getTypeOfLiteralOrExpression((<CaseClause>clause).expression) : undefined;
|
||||||
const expr = (<CaseClause>clause).expression;
|
|
||||||
return expr.kind === SyntaxKind.StringLiteral ? getStringLiteralTypeForText((<StringLiteral>expr).text) : checkExpression(expr);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSwitchClauseTypes(switchStatement: SwitchStatement): Type[] {
|
function getSwitchClauseTypes(switchStatement: SwitchStatement): Type[] {
|
||||||
|
@ -8021,11 +8057,11 @@ namespace ts {
|
||||||
}
|
}
|
||||||
const propName = propAccess.name.text;
|
const propName = propAccess.name.text;
|
||||||
const propType = getTypeOfPropertyOfType(type, propName);
|
const propType = getTypeOfPropertyOfType(type, propName);
|
||||||
if (!propType || !isStringLiteralUnionType(propType)) {
|
if (!propType || !isLiteralUnionType(propType)) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
const discriminantType = value.kind === SyntaxKind.StringLiteral ? getStringLiteralTypeForText((<StringLiteral>value).text) : checkExpression(value);
|
const discriminantType = getTypeOfLiteralOrExpression(value);
|
||||||
if (!isStringLiteralUnionType(discriminantType)) {
|
if (!isLiteralUnionType(discriminantType)) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||||
|
@ -8047,7 +8083,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
const propName = (<PropertyAccessExpression>switchStatement.expression).name.text;
|
const propName = (<PropertyAccessExpression>switchStatement.expression).name.text;
|
||||||
const propType = getTypeOfPropertyOfType(type, propName);
|
const propType = getTypeOfPropertyOfType(type, propName);
|
||||||
if (!propType || !isStringLiteralUnionType(propType)) {
|
if (!propType || !isLiteralUnionType(propType)) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
const switchTypes = getSwitchClauseTypes(switchStatement);
|
const switchTypes = getSwitchClauseTypes(switchStatement);
|
||||||
|
@ -10446,7 +10482,7 @@ namespace ts {
|
||||||
|
|
||||||
// specialized signatures always need to be placed before non-specialized signatures regardless
|
// specialized signatures always need to be placed before non-specialized signatures regardless
|
||||||
// of the cutoff position; see GH#1133
|
// of the cutoff position; see GH#1133
|
||||||
if (signature.hasStringLiterals) {
|
if (signature.hasLiteralTypes) {
|
||||||
specializedIndex++;
|
specializedIndex++;
|
||||||
spliceIndex = specializedIndex;
|
spliceIndex = specializedIndex;
|
||||||
// The cutoff index always needs to be greater than or equal to the specialized signature index
|
// The cutoff index always needs to be greater than or equal to the specialized signature index
|
||||||
|
@ -10705,7 +10741,7 @@ namespace ts {
|
||||||
// for the argument. In that case, we should check the argument.
|
// for the argument. In that case, we should check the argument.
|
||||||
if (argType === undefined) {
|
if (argType === undefined) {
|
||||||
argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors
|
argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors
|
||||||
? getStringLiteralTypeForText((<StringLiteral>arg).text)
|
? getTypeFromLiteralExpression(arg)
|
||||||
: checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
|
: checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11877,7 +11913,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
const propName = (<PropertyAccessExpression>expr).name.text;
|
const propName = (<PropertyAccessExpression>expr).name.text;
|
||||||
const propType = getTypeOfPropertyOfType(type, propName);
|
const propType = getTypeOfPropertyOfType(type, propName);
|
||||||
if (!propType || !isStringLiteralUnionType(propType)) {
|
if (!propType || !isLiteralUnionType(propType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const switchTypes = getSwitchClauseTypes(node);
|
const switchTypes = getSwitchClauseTypes(node);
|
||||||
|
@ -12217,6 +12253,9 @@ namespace ts {
|
||||||
|
|
||||||
function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
|
function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
|
||||||
const operandType = checkExpression(node.operand);
|
const operandType = checkExpression(node.operand);
|
||||||
|
if (node.operator === SyntaxKind.MinusToken && node.operand.kind === SyntaxKind.NumericLiteral && hasLiteralContextualType(node)) {
|
||||||
|
return getTypeFromLiteralExpression(node);
|
||||||
|
}
|
||||||
switch (node.operator) {
|
switch (node.operator) {
|
||||||
case SyntaxKind.PlusToken:
|
case SyntaxKind.PlusToken:
|
||||||
case SyntaxKind.MinusToken:
|
case SyntaxKind.MinusToken:
|
||||||
|
@ -12520,8 +12559,8 @@ namespace ts {
|
||||||
let suggestedOperator: SyntaxKind;
|
let suggestedOperator: SyntaxKind;
|
||||||
// if a user tries to apply a bitwise operator to 2 boolean operands
|
// if a user tries to apply a bitwise operator to 2 boolean operands
|
||||||
// try and return them a helpful suggestion
|
// try and return them a helpful suggestion
|
||||||
if ((leftType.flags & TypeFlags.Boolean) &&
|
if ((leftType.flags & TypeFlags.BooleanLike) &&
|
||||||
(rightType.flags & TypeFlags.Boolean) &&
|
(rightType.flags & TypeFlags.BooleanLike) &&
|
||||||
(suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
|
(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));
|
error(errorNode || operatorToken, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(operatorToken.kind), tokenToString(suggestedOperator));
|
||||||
}
|
}
|
||||||
|
@ -12734,13 +12773,18 @@ namespace ts {
|
||||||
return getUnionType([type1, type2]);
|
return getUnionType([type1, type2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkStringLiteralExpression(node: StringLiteral): Type {
|
function hasLiteralContextualType(node: Expression) {
|
||||||
const contextualType = getContextualType(node);
|
return isLiteralUnionType(getContextualType(node) || unknownType);
|
||||||
if (contextualType && isStringLiteralUnionType(contextualType)) {
|
|
||||||
return getStringLiteralTypeForText(node.text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return stringType;
|
function checkLiteralExpression(node: Expression): Type {
|
||||||
|
const type = node.kind === SyntaxKind.StringLiteral ? stringType :
|
||||||
|
node.kind === SyntaxKind.TrueKeyword || node.kind === SyntaxKind.FalseKeyword ? booleanType :
|
||||||
|
numberType;
|
||||||
|
if (type === numberType) {
|
||||||
|
checkGrammarNumericLiteral(<LiteralExpression>node);
|
||||||
|
}
|
||||||
|
return hasLiteralContextualType(node) ? getTypeFromLiteralExpression(node) : type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkTemplateExpression(node: TemplateExpression): Type {
|
function checkTemplateExpression(node: TemplateExpression): Type {
|
||||||
|
@ -12855,12 +12899,6 @@ namespace ts {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkNumericLiteral(node: LiteralExpression): Type {
|
|
||||||
// Grammar checking
|
|
||||||
checkGrammarNumericLiteral(node);
|
|
||||||
return numberType;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkExpressionWorker(node: Expression, contextualMapper: TypeMapper): Type {
|
function checkExpressionWorker(node: Expression, contextualMapper: TypeMapper): Type {
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
case SyntaxKind.Identifier:
|
case SyntaxKind.Identifier:
|
||||||
|
@ -12871,15 +12909,13 @@ namespace ts {
|
||||||
return checkSuperExpression(node);
|
return checkSuperExpression(node);
|
||||||
case SyntaxKind.NullKeyword:
|
case SyntaxKind.NullKeyword:
|
||||||
return nullWideningType;
|
return nullWideningType;
|
||||||
|
case SyntaxKind.StringLiteral:
|
||||||
|
case SyntaxKind.NumericLiteral:
|
||||||
case SyntaxKind.TrueKeyword:
|
case SyntaxKind.TrueKeyword:
|
||||||
case SyntaxKind.FalseKeyword:
|
case SyntaxKind.FalseKeyword:
|
||||||
return booleanType;
|
return checkLiteralExpression(node);
|
||||||
case SyntaxKind.NumericLiteral:
|
|
||||||
return checkNumericLiteral(<LiteralExpression>node);
|
|
||||||
case SyntaxKind.TemplateExpression:
|
case SyntaxKind.TemplateExpression:
|
||||||
return checkTemplateExpression(<TemplateExpression>node);
|
return checkTemplateExpression(<TemplateExpression>node);
|
||||||
case SyntaxKind.StringLiteral:
|
|
||||||
return checkStringLiteralExpression(<StringLiteral>node);
|
|
||||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||||
return stringType;
|
return stringType;
|
||||||
case SyntaxKind.RegularExpressionLiteral:
|
case SyntaxKind.RegularExpressionLiteral:
|
||||||
|
@ -17605,7 +17641,7 @@ namespace ts {
|
||||||
else if (isTypeOfKind(type, TypeFlags.Void)) {
|
else if (isTypeOfKind(type, TypeFlags.Void)) {
|
||||||
return TypeReferenceSerializationKind.VoidType;
|
return TypeReferenceSerializationKind.VoidType;
|
||||||
}
|
}
|
||||||
else if (isTypeOfKind(type, TypeFlags.Boolean)) {
|
else if (isTypeOfKind(type, TypeFlags.BooleanLike)) {
|
||||||
return TypeReferenceSerializationKind.BooleanType;
|
return TypeReferenceSerializationKind.BooleanType;
|
||||||
}
|
}
|
||||||
else if (isTypeOfKind(type, TypeFlags.NumberLike)) {
|
else if (isTypeOfKind(type, TypeFlags.NumberLike)) {
|
||||||
|
|
|
@ -397,7 +397,7 @@ namespace ts {
|
||||||
case SyntaxKind.NullKeyword:
|
case SyntaxKind.NullKeyword:
|
||||||
case SyntaxKind.NeverKeyword:
|
case SyntaxKind.NeverKeyword:
|
||||||
case SyntaxKind.ThisType:
|
case SyntaxKind.ThisType:
|
||||||
case SyntaxKind.StringLiteralType:
|
case SyntaxKind.LiteralType:
|
||||||
return writeTextOfNode(currentText, type);
|
return writeTextOfNode(currentText, type);
|
||||||
case SyntaxKind.ExpressionWithTypeArguments:
|
case SyntaxKind.ExpressionWithTypeArguments:
|
||||||
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>type);
|
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>type);
|
||||||
|
|
|
@ -6009,7 +6009,7 @@ const _super = (function (geti, seti) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case SyntaxKind.StringKeyword:
|
case SyntaxKind.StringKeyword:
|
||||||
case SyntaxKind.StringLiteralType:
|
case SyntaxKind.LiteralType:
|
||||||
write("String");
|
write("String");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,8 @@ namespace ts {
|
||||||
return visitNodes(cbNodes, (<UnionOrIntersectionTypeNode>node).types);
|
return visitNodes(cbNodes, (<UnionOrIntersectionTypeNode>node).types);
|
||||||
case SyntaxKind.ParenthesizedType:
|
case SyntaxKind.ParenthesizedType:
|
||||||
return visitNode(cbNode, (<ParenthesizedTypeNode>node).type);
|
return visitNode(cbNode, (<ParenthesizedTypeNode>node).type);
|
||||||
|
case SyntaxKind.LiteralType:
|
||||||
|
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
|
||||||
case SyntaxKind.ObjectBindingPattern:
|
case SyntaxKind.ObjectBindingPattern:
|
||||||
case SyntaxKind.ArrayBindingPattern:
|
case SyntaxKind.ArrayBindingPattern:
|
||||||
return visitNodes(cbNodes, (<BindingPattern>node).elements);
|
return visitNodes(cbNodes, (<BindingPattern>node).elements);
|
||||||
|
@ -1918,10 +1920,6 @@ namespace ts {
|
||||||
return finishNode(span);
|
return finishNode(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseStringLiteralTypeNode(): StringLiteralTypeNode {
|
|
||||||
return <StringLiteralTypeNode>parseLiteralLikeNode(SyntaxKind.StringLiteralType, /*internName*/ true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseLiteralNode(internName?: boolean): LiteralExpression {
|
function parseLiteralNode(internName?: boolean): LiteralExpression {
|
||||||
return <LiteralExpression>parseLiteralLikeNode(token, internName);
|
return <LiteralExpression>parseLiteralLikeNode(token, internName);
|
||||||
}
|
}
|
||||||
|
@ -2387,6 +2385,17 @@ namespace ts {
|
||||||
return token === SyntaxKind.DotToken ? undefined : node;
|
return token === SyntaxKind.DotToken ? undefined : node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseLiteralTypeNode(): LiteralTypeNode {
|
||||||
|
const node = <LiteralTypeNode>createNode(SyntaxKind.LiteralType);
|
||||||
|
node.literal = parseSimpleUnaryExpression();
|
||||||
|
finishNode(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextTokenIsNumericLiteral() {
|
||||||
|
return nextToken() === SyntaxKind.NumericLiteral;
|
||||||
|
}
|
||||||
|
|
||||||
function parseNonArrayType(): TypeNode {
|
function parseNonArrayType(): TypeNode {
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case SyntaxKind.AnyKeyword:
|
case SyntaxKind.AnyKeyword:
|
||||||
|
@ -2400,7 +2409,12 @@ namespace ts {
|
||||||
const node = tryParse(parseKeywordAndNoDot);
|
const node = tryParse(parseKeywordAndNoDot);
|
||||||
return node || parseTypeReference();
|
return node || parseTypeReference();
|
||||||
case SyntaxKind.StringLiteral:
|
case SyntaxKind.StringLiteral:
|
||||||
return parseStringLiteralTypeNode();
|
case SyntaxKind.NumericLiteral:
|
||||||
|
case SyntaxKind.TrueKeyword:
|
||||||
|
case SyntaxKind.FalseKeyword:
|
||||||
|
return parseLiteralTypeNode();
|
||||||
|
case SyntaxKind.MinusToken:
|
||||||
|
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode() : parseTypeReference();
|
||||||
case SyntaxKind.VoidKeyword:
|
case SyntaxKind.VoidKeyword:
|
||||||
case SyntaxKind.NullKeyword:
|
case SyntaxKind.NullKeyword:
|
||||||
return parseTokenNode<TypeNode>();
|
return parseTokenNode<TypeNode>();
|
||||||
|
@ -2444,7 +2458,12 @@ namespace ts {
|
||||||
case SyntaxKind.LessThanToken:
|
case SyntaxKind.LessThanToken:
|
||||||
case SyntaxKind.NewKeyword:
|
case SyntaxKind.NewKeyword:
|
||||||
case SyntaxKind.StringLiteral:
|
case SyntaxKind.StringLiteral:
|
||||||
|
case SyntaxKind.NumericLiteral:
|
||||||
|
case SyntaxKind.TrueKeyword:
|
||||||
|
case SyntaxKind.FalseKeyword:
|
||||||
return true;
|
return true;
|
||||||
|
case SyntaxKind.MinusToken:
|
||||||
|
return lookAhead(nextTokenIsNumericLiteral);
|
||||||
case SyntaxKind.OpenParenToken:
|
case SyntaxKind.OpenParenToken:
|
||||||
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
||||||
// or something that starts a type. We don't want to consider things like '(1)' a type.
|
// or something that starts a type. We don't want to consider things like '(1)' a type.
|
||||||
|
|
|
@ -210,7 +210,7 @@ namespace ts {
|
||||||
IntersectionType,
|
IntersectionType,
|
||||||
ParenthesizedType,
|
ParenthesizedType,
|
||||||
ThisType,
|
ThisType,
|
||||||
StringLiteralType,
|
LiteralType,
|
||||||
// Binding patterns
|
// Binding patterns
|
||||||
ObjectBindingPattern,
|
ObjectBindingPattern,
|
||||||
ArrayBindingPattern,
|
ArrayBindingPattern,
|
||||||
|
@ -361,7 +361,7 @@ namespace ts {
|
||||||
FirstFutureReservedWord = ImplementsKeyword,
|
FirstFutureReservedWord = ImplementsKeyword,
|
||||||
LastFutureReservedWord = YieldKeyword,
|
LastFutureReservedWord = YieldKeyword,
|
||||||
FirstTypeNode = TypePredicate,
|
FirstTypeNode = TypePredicate,
|
||||||
LastTypeNode = StringLiteralType,
|
LastTypeNode = LiteralType,
|
||||||
FirstPunctuation = OpenBraceToken,
|
FirstPunctuation = OpenBraceToken,
|
||||||
LastPunctuation = CaretEqualsToken,
|
LastPunctuation = CaretEqualsToken,
|
||||||
FirstToken = Unknown,
|
FirstToken = Unknown,
|
||||||
|
@ -790,8 +790,9 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// @kind(SyntaxKind.StringLiteralType)
|
// @kind(SyntaxKind.StringLiteralType)
|
||||||
export interface StringLiteralTypeNode extends LiteralLikeNode, TypeNode {
|
export interface LiteralTypeNode extends TypeNode {
|
||||||
_stringLiteralTypeBrand: any;
|
_stringLiteralTypeBrand: any;
|
||||||
|
literal: Expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @kind(SyntaxKind.StringLiteral)
|
// @kind(SyntaxKind.StringLiteral)
|
||||||
|
@ -2197,50 +2198,54 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum TypeFlags {
|
export const enum TypeFlags {
|
||||||
Any = 0x00000001,
|
Any = 1 << 0,
|
||||||
String = 0x00000002,
|
String = 1 << 1,
|
||||||
Number = 0x00000004,
|
Number = 1 << 2,
|
||||||
Boolean = 0x00000008,
|
Boolean = 1 << 3,
|
||||||
Void = 0x00000010,
|
StringLiteral = 1 << 4, // String literal type
|
||||||
Undefined = 0x00000020,
|
NumberLiteral = 1 << 5,
|
||||||
Null = 0x00000040,
|
BooleanLiteral = 1 << 6,
|
||||||
Enum = 0x00000080, // Enum type
|
ESSymbol = 1 << 7, // Type of symbol primitive introduced in ES6
|
||||||
StringLiteral = 0x00000100, // String literal type
|
Void = 1 << 8,
|
||||||
TypeParameter = 0x00000200, // Type parameter
|
Undefined = 1 << 9,
|
||||||
Class = 0x00000400, // Class
|
Null = 1 << 10,
|
||||||
Interface = 0x00000800, // Interface
|
Never = 1 << 11, // Never type
|
||||||
Reference = 0x00001000, // Generic type reference
|
Enum = 1 << 12, // Enum type
|
||||||
Tuple = 0x00002000, // Tuple
|
TypeParameter = 1 << 13, // Type parameter
|
||||||
Union = 0x00004000, // Union (T | U)
|
Class = 1 << 14, // Class
|
||||||
Intersection = 0x00008000, // Intersection (T & U)
|
Interface = 1 << 15, // Interface
|
||||||
Anonymous = 0x00010000, // Anonymous
|
Reference = 1 << 16, // Generic type reference
|
||||||
Instantiated = 0x00020000, // Instantiated anonymous type
|
Tuple = 1 << 17, // Tuple
|
||||||
|
Union = 1 << 18, // Union (T | U)
|
||||||
|
Intersection = 1 << 19, // Intersection (T & U)
|
||||||
|
Anonymous = 1 << 20, // Anonymous
|
||||||
|
Instantiated = 1 << 21, // Instantiated anonymous type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
FromSignature = 0x00040000, // Created for signature assignment check
|
FromSignature = 1 << 22, // Created for signature assignment check
|
||||||
ObjectLiteral = 0x00080000, // Originates in an object literal
|
ObjectLiteral = 1 << 23, // Originates in an object literal
|
||||||
/* @internal */
|
/* @internal */
|
||||||
FreshObjectLiteral = 0x00100000, // Fresh object literal type
|
FreshObjectLiteral = 1 << 24, // Fresh object literal type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsWideningType = 0x00200000, // Type is or contains undefined or null widening type
|
ContainsWideningType = 1 << 25, // Type is or contains undefined or null widening type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsObjectLiteral = 0x00400000, // Type is or contains object literal type
|
ContainsObjectLiteral = 1 << 26, // Type is or contains object literal type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type
|
ContainsAnyFunctionType = 1 << 27, // Type is or contains object literal type
|
||||||
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
|
ThisType = 1 << 28, // This type
|
||||||
ThisType = 0x02000000, // This type
|
ObjectLiteralPatternWithComputedProperties = 1 << 29, // Object literal type implied by binding pattern has computed properties
|
||||||
ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties
|
|
||||||
Never = 0x08000000, // Never type
|
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
Nullable = Undefined | Null,
|
Nullable = Undefined | Null,
|
||||||
|
Literal = StringLiteral | NumberLiteral | BooleanLiteral,
|
||||||
/* @internal */
|
/* @internal */
|
||||||
Falsy = Void | Undefined | Null, // TODO: Add false, 0, and ""
|
Falsy = Void | Undefined | Null, // TODO: Add false, 0, and ""
|
||||||
/* @internal */
|
/* @internal */
|
||||||
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null | Never,
|
Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never,
|
||||||
/* @internal */
|
/* @internal */
|
||||||
Primitive = String | Number | Boolean | ESSymbol | Void | Undefined | Null | StringLiteral | Enum,
|
Primitive = String | Number | Boolean | ESSymbol | Void | Undefined | Null | StringLiteral | Enum,
|
||||||
StringLike = String | StringLiteral,
|
StringLike = String | StringLiteral,
|
||||||
NumberLike = Number | Enum,
|
NumberLike = Number | NumberLiteral | Enum,
|
||||||
|
BooleanLike = Boolean | BooleanLiteral,
|
||||||
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
|
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
|
||||||
UnionOrIntersection = Union | Intersection,
|
UnionOrIntersection = Union | Intersection,
|
||||||
StructuredType = ObjectType | Union | Intersection,
|
StructuredType = ObjectType | Union | Intersection,
|
||||||
|
@ -2271,7 +2276,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// String literal types (TypeFlags.StringLiteral)
|
// String literal types (TypeFlags.StringLiteral)
|
||||||
export interface StringLiteralType extends Type {
|
export interface LiteralType extends Type {
|
||||||
text: string; // Text of string literal
|
text: string; // Text of string literal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2394,7 +2399,7 @@ namespace ts {
|
||||||
/* @internal */
|
/* @internal */
|
||||||
hasRestParameter: boolean; // True if last parameter is rest parameter
|
hasRestParameter: boolean; // True if last parameter is rest parameter
|
||||||
/* @internal */
|
/* @internal */
|
||||||
hasStringLiterals: boolean; // True if specialized
|
hasLiteralTypes: boolean; // True if specialized
|
||||||
/* @internal */
|
/* @internal */
|
||||||
target?: Signature; // Instantiation target
|
target?: Signature; // Instantiation target
|
||||||
/* @internal */
|
/* @internal */
|
||||||
|
|
|
@ -783,7 +783,7 @@ namespace ts {
|
||||||
resolvedReturnType: Type;
|
resolvedReturnType: Type;
|
||||||
minArgumentCount: number;
|
minArgumentCount: number;
|
||||||
hasRestParameter: boolean;
|
hasRestParameter: boolean;
|
||||||
hasStringLiterals: boolean;
|
hasLiteralTypes: boolean;
|
||||||
|
|
||||||
// Undefined is used to indicate the value has not been computed. If, after computing, the
|
// Undefined is used to indicate the value has not been computed. If, after computing, the
|
||||||
// symbol has no doc comment, then the empty string will be returned.
|
// symbol has no doc comment, then the empty string will be returned.
|
||||||
|
@ -3633,7 +3633,6 @@ namespace ts {
|
||||||
|
|
||||||
function isInStringOrRegularExpressionOrTemplateLiteral(contextToken: Node): boolean {
|
function isInStringOrRegularExpressionOrTemplateLiteral(contextToken: Node): boolean {
|
||||||
if (contextToken.kind === SyntaxKind.StringLiteral
|
if (contextToken.kind === SyntaxKind.StringLiteral
|
||||||
|| contextToken.kind === SyntaxKind.StringLiteralType
|
|
||||||
|| contextToken.kind === SyntaxKind.RegularExpressionLiteral
|
|| contextToken.kind === SyntaxKind.RegularExpressionLiteral
|
||||||
|| isTemplateLiteralKind(contextToken.kind)) {
|
|| isTemplateLiteralKind(contextToken.kind)) {
|
||||||
const start = contextToken.getStart();
|
const start = contextToken.getStart();
|
||||||
|
@ -4298,7 +4297,7 @@ namespace ts {
|
||||||
else {
|
else {
|
||||||
if (type.flags & TypeFlags.StringLiteral) {
|
if (type.flags & TypeFlags.StringLiteral) {
|
||||||
result.push({
|
result.push({
|
||||||
name: (<StringLiteralType>type).text,
|
name: (<LiteralType>type).text,
|
||||||
kindModifiers: ScriptElementKindModifier.none,
|
kindModifiers: ScriptElementKindModifier.none,
|
||||||
kind: ScriptElementKind.variableElement,
|
kind: ScriptElementKind.variableElement,
|
||||||
sortText: "0"
|
sortText: "0"
|
||||||
|
@ -6985,7 +6984,6 @@ namespace ts {
|
||||||
case SyntaxKind.PropertyAccessExpression:
|
case SyntaxKind.PropertyAccessExpression:
|
||||||
case SyntaxKind.QualifiedName:
|
case SyntaxKind.QualifiedName:
|
||||||
case SyntaxKind.StringLiteral:
|
case SyntaxKind.StringLiteral:
|
||||||
case SyntaxKind.StringLiteralType:
|
|
||||||
case SyntaxKind.FalseKeyword:
|
case SyntaxKind.FalseKeyword:
|
||||||
case SyntaxKind.TrueKeyword:
|
case SyntaxKind.TrueKeyword:
|
||||||
case SyntaxKind.NullKeyword:
|
case SyntaxKind.NullKeyword:
|
||||||
|
@ -7489,7 +7487,7 @@ namespace ts {
|
||||||
else if (tokenKind === SyntaxKind.NumericLiteral) {
|
else if (tokenKind === SyntaxKind.NumericLiteral) {
|
||||||
return ClassificationType.numericLiteral;
|
return ClassificationType.numericLiteral;
|
||||||
}
|
}
|
||||||
else if (tokenKind === SyntaxKind.StringLiteral || tokenKind === SyntaxKind.StringLiteralType) {
|
else if (tokenKind === SyntaxKind.StringLiteral) {
|
||||||
return token.parent.kind === SyntaxKind.JsxAttribute ? ClassificationType.jsxAttributeStringLiteralValue : ClassificationType.stringLiteral;
|
return token.parent.kind === SyntaxKind.JsxAttribute ? ClassificationType.jsxAttributeStringLiteralValue : ClassificationType.stringLiteral;
|
||||||
}
|
}
|
||||||
else if (tokenKind === SyntaxKind.RegularExpressionLiteral) {
|
else if (tokenKind === SyntaxKind.RegularExpressionLiteral) {
|
||||||
|
@ -7983,11 +7981,11 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringLiteralTypeForNode(node: StringLiteral | StringLiteralTypeNode, typeChecker: TypeChecker): StringLiteralType {
|
function getStringLiteralTypeForNode(node: StringLiteral | LiteralTypeNode, typeChecker: TypeChecker): LiteralType {
|
||||||
const searchNode = node.parent.kind === SyntaxKind.StringLiteralType ? <StringLiteralTypeNode>node.parent : node;
|
const searchNode = node.parent.kind === SyntaxKind.LiteralType ? <LiteralTypeNode>node.parent : node;
|
||||||
const type = typeChecker.getTypeAtLocation(searchNode);
|
const type = typeChecker.getTypeAtLocation(searchNode);
|
||||||
if (type && type.flags & TypeFlags.StringLiteral) {
|
if (type && type.flags & TypeFlags.StringLiteral) {
|
||||||
return <StringLiteralType>type;
|
return <LiteralType>type;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -8474,7 +8472,7 @@ namespace ts {
|
||||||
addResult(start, end, classFromKind(token));
|
addResult(start, end, classFromKind(token));
|
||||||
|
|
||||||
if (end >= text.length) {
|
if (end >= text.length) {
|
||||||
if (token === SyntaxKind.StringLiteral || token === SyntaxKind.StringLiteralType) {
|
if (token === SyntaxKind.StringLiteral) {
|
||||||
// Check to see if we finished up on a multiline string literal.
|
// Check to see if we finished up on a multiline string literal.
|
||||||
const tokenText = scanner.getTokenText();
|
const tokenText = scanner.getTokenText();
|
||||||
if (scanner.isUnterminated()) {
|
if (scanner.isUnterminated()) {
|
||||||
|
@ -8624,7 +8622,6 @@ namespace ts {
|
||||||
case SyntaxKind.NumericLiteral:
|
case SyntaxKind.NumericLiteral:
|
||||||
return ClassificationType.numericLiteral;
|
return ClassificationType.numericLiteral;
|
||||||
case SyntaxKind.StringLiteral:
|
case SyntaxKind.StringLiteral:
|
||||||
case SyntaxKind.StringLiteralType:
|
|
||||||
return ClassificationType.stringLiteral;
|
return ClassificationType.stringLiteral;
|
||||||
case SyntaxKind.RegularExpressionLiteral:
|
case SyntaxKind.RegularExpressionLiteral:
|
||||||
return ClassificationType.regularExpressionLiteral;
|
return ClassificationType.regularExpressionLiteral;
|
||||||
|
|
|
@ -428,8 +428,7 @@ namespace ts {
|
||||||
|
|
||||||
export function isInString(sourceFile: SourceFile, position: number): boolean {
|
export function isInString(sourceFile: SourceFile, position: number): boolean {
|
||||||
const previousToken = findPrecedingToken(position, sourceFile);
|
const previousToken = findPrecedingToken(position, sourceFile);
|
||||||
if (previousToken &&
|
if (previousToken && previousToken.kind === SyntaxKind.StringLiteral) {
|
||||||
(previousToken.kind === SyntaxKind.StringLiteral || previousToken.kind === SyntaxKind.StringLiteralType)) {
|
|
||||||
const start = previousToken.getStart();
|
const start = previousToken.getStart();
|
||||||
const end = previousToken.getEnd();
|
const end = previousToken.getEnd();
|
||||||
|
|
||||||
|
@ -627,7 +626,6 @@ namespace ts {
|
||||||
|
|
||||||
export function isStringOrRegularExpressionOrTemplateLiteral(kind: SyntaxKind): boolean {
|
export function isStringOrRegularExpressionOrTemplateLiteral(kind: SyntaxKind): boolean {
|
||||||
if (kind === SyntaxKind.StringLiteral
|
if (kind === SyntaxKind.StringLiteral
|
||||||
|| kind === SyntaxKind.StringLiteralType
|
|
||||||
|| kind === SyntaxKind.RegularExpressionLiteral
|
|| kind === SyntaxKind.RegularExpressionLiteral
|
||||||
|| isTemplateLiteralKind(kind)) {
|
|| isTemplateLiteralKind(kind)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue