New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow dynamic names in types #15473

Merged
merged 65 commits into from Nov 16, 2017
Commits
Jump to file or symbol
Failed to load files and symbols.
+66 −48
Diff settings

Always

Just for now

Viewing a subset of changes. View all

Merge branch 'master' into dynamicNames

  • Loading branch information...
rbuckton committed May 31, 2017
commit 625b37e7b4867b328f43fba1e659c197d2179600
Copy path View file
@@ -2409,11 +2409,7 @@ namespace ts {
if (type.flags & TypeFlags.Unique) {
return type.flags & TypeFlags.Fresh
? <SymbolTypeNode>createToken(SyntaxKind.SymbolType)
: createTypeQueryNodeFromSymbol(type.symbol);
}
if (type.flags & TypeFlags.EnumLiteral) {
const name = symbolToName(type.symbol, /*expectsIdentifier*/ false);
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
: createTypeQueryNodeFromSymbol(type.symbol, SymbolFlags.Value);
}
if (type.flags & TypeFlags.Void) {
return createKeywordTypeNode(SyntaxKind.VoidKeyword);
@@ -4264,7 +4260,7 @@ namespace ts {
const func = <FunctionLikeDeclaration>declaration.parent;
// For a parameter of a set accessor, use the type of the get accessor if one is present
if (func.kind === SyntaxKind.SetAccessor && !hasUnboundDynamicName(func)) {
const getter = <AccessorDeclaration>getDeclarationOfKind(getSymbolOfNode(declaration.parent), SyntaxKind.GetAccessor);
const getter = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(declaration.parent), SyntaxKind.GetAccessor);
if (getter) {
const getterSignature = getSignatureFromDeclaration(getter);
const thisParameter = getAccessorThisParameter(func as AccessorDeclaration);
@@ -5398,7 +5394,8 @@ namespace ts {
* Tests whether a declaration has a late-bound dynamic name.
*/
function hasLateBoundName(node: Declaration): node is LateBoundDeclaration {
return node.name && isLateBoundName(node.name);
const name = getNameOfDeclaration(node);
return name && isLateBoundName(name);
}
/**
@@ -5446,7 +5443,7 @@ namespace ts {
return `__@${type.symbol.name}@${getSymbolId(type.symbol)}`;
}
if (type.flags & TypeFlags.StringOrNumberLiteral) {
return escapeIdentifier((<LiteralType>type).text);
return escapeIdentifier("" + (<LiteralType>type).value);
}
}
@@ -5492,7 +5489,7 @@ namespace ts {
if (symbol.flags & getExcludedSymbolFlags(memberSymbol.flags) || staticMember) {
const declarations = staticMember ? concatenate(staticMember.declarations, symbol.declarations) : symbol.declarations;
const name = declarationNameToString(member.name);
forEach(declarations, declaration => error(declaration.name || declaration, Diagnostics.Duplicate_declaration_0, name));
forEach(declarations, declaration => error(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_declaration_0, name));
error(member.name || member, Diagnostics.Duplicate_declaration_0, name);
symbol = createSymbol(SymbolFlags.Late, memberName);
}
@@ -6566,7 +6563,7 @@ namespace ts {
!hasUnboundDynamicName(declaration) &&
(!hasThisParameter || !thisParameter)) {
const otherKind = declaration.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
const other = <AccessorDeclaration>getDeclarationOfKind(getSymbolOfNode(declaration), otherKind);
const other = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(declaration), otherKind);
if (other) {
thisParameter = getAnnotatedAccessorThisParameter(other);
}
@@ -6609,7 +6606,7 @@ namespace ts {
// TypeScript 1.0 spec (April 2014):
// If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
if (declaration.kind === SyntaxKind.GetAccessor && !hasUnboundDynamicName(declaration)) {
const setter = <AccessorDeclaration>getDeclarationOfKind(getSymbolOfNode(declaration), SyntaxKind.SetAccessor);
const setter = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(declaration), SyntaxKind.SetAccessor);
return getAnnotatedAccessorType(setter);
}
@@ -7940,7 +7937,7 @@ namespace ts {
if (!(<UniqueType | LiteralType>type).freshType) {
const freshType = type.flags & TypeFlags.Unique
? createUniqueType(type.symbol, TypeFlags.Fresh)
: createLiteralType(type.flags | TypeFlags.Fresh, (<LiteralType>type).text);
: createLiteralType(type.flags | TypeFlags.Fresh, (<LiteralType>type).value, (<LiteralType>type).symbol);
freshType.regularType = <UniqueType | LiteralType>type;
(<UniqueType | LiteralType>type).freshType = freshType;
}
@@ -8862,18 +8859,31 @@ namespace ts {
}
function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorReporter?: ErrorReporter) {
if (target.flags & TypeFlags.Never) return false;
if (target.flags & TypeFlags.Any || source.flags & TypeFlags.Never) return true;
if (source.flags & TypeFlags.StringLike && target.flags & TypeFlags.String) return true;
if (source.flags & TypeFlags.NumberLike && target.flags & TypeFlags.Number) return true;
if (source.flags & TypeFlags.BooleanLike && target.flags & TypeFlags.Boolean) return true;
if (source.flags & TypeFlags.ESSymbolLike && target.flags & TypeFlags.ESSymbol) return true;
if (source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.Enum && (<EnumLiteralType>source).baseType === target) return true;
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum && isEnumTypeRelatedTo(<EnumType>source, <EnumType>target, errorReporter)) return true;
if (source.flags & TypeFlags.Undefined && (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void))) return true;
if (source.flags & TypeFlags.Null && (!strictNullChecks || target.flags & TypeFlags.Null)) return true;
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.NonPrimitive) return true;
if (source.flags & TypeFlags.Unique || target.flags & TypeFlags.Unique) return false;
const s = source.flags;
const t = target.flags;
if (t & TypeFlags.Never) return false;
if (t & TypeFlags.Any || s & TypeFlags.Never) return true;
if (s & TypeFlags.StringLike && t & TypeFlags.String) return true;
if (s & TypeFlags.StringLiteral && s & TypeFlags.EnumLiteral &&
t & TypeFlags.StringLiteral && !(t & TypeFlags.EnumLiteral) &&
(<LiteralType>source).value === (<LiteralType>target).value) return true;
if (s & TypeFlags.NumberLike && t & TypeFlags.Number) return true;
if (s & TypeFlags.NumberLiteral && s & TypeFlags.EnumLiteral &&
t & TypeFlags.NumberLiteral && !(t & TypeFlags.EnumLiteral) &&
(<LiteralType>source).value === (<LiteralType>target).value) return true;
if (s & TypeFlags.BooleanLike && t & TypeFlags.Boolean) return true;
if (s & TypeFlags.ESSymbolLike && t & TypeFlags.ESSymbol) return true;
if (s & TypeFlags.Enum && t & TypeFlags.Enum && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true;
if (s & TypeFlags.EnumLiteral && t & TypeFlags.EnumLiteral) {
if (s & TypeFlags.Union && t & TypeFlags.Union && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true;
if (s & TypeFlags.Literal && t & TypeFlags.Literal &&
(<LiteralType>source).value === (<LiteralType>target).value &&
isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter)) return true;
}
if (s & TypeFlags.Undefined && (!strictNullChecks || t & (TypeFlags.Undefined | TypeFlags.Void))) return true;
if (s & TypeFlags.Null && (!strictNullChecks || t & TypeFlags.Null)) return true;
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive) return true;
if (s & TypeFlags.Unique || t & TypeFlags.Unique) return false;
if (relation === assignableRelation || relation === comparableRelation) {
if (s & TypeFlags.Any) return true;
// Type number or any numeric literal type is assignable to any numeric enum type or any
@@ -10105,13 +10115,13 @@ namespace ts {
}
function getWidenedLiteralType(type: Type): Type {
return type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.Fresh ? stringType :
return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.Fresh ? stringType :
type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.Fresh ? numberType :
type.flags & TypeFlags.Unique && type.flags & TypeFlags.Fresh ? esSymbolType :
type.flags & TypeFlags.BooleanLiteral ? booleanType :
type.flags & TypeFlags.EnumLiteral ? (<EnumLiteralType>type).baseType :
type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((<UnionType>type).types, getWidenedLiteralType)) :
type;
type.flags & TypeFlags.Unique && type.flags & TypeFlags.Fresh ? esSymbolType :
type.flags & TypeFlags.BooleanLiteral ? booleanType :
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getWidenedLiteralType)) :
type;
}
/**
@@ -13634,7 +13644,7 @@ namespace ts {
if (spread.flags & TypeFlags.Object) {
// only set the symbol and flags if this is a (fresh) object type
spread.flags |= propagatedFlags;
spread.flags |= TypeFlags.FreshLiteral;
spread.flags |= TypeFlags.Fresh;
(spread as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral;
spread.symbol = node.symbol;
}
@@ -17055,7 +17065,7 @@ namespace ts {
return silentNeverType;
}
if (node.operator === SyntaxKind.MinusToken && node.operand.kind === SyntaxKind.NumericLiteral) {
return getFreshTypeOfLiteralOrUniqueType(getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>node.operand).text));
return getFreshTypeOfLiteralOrUniqueType(getLiteralType(-(<LiteralExpression>node.operand).text));
}
switch (node.operator) {
case SyntaxKind.PlusToken:
@@ -17735,9 +17745,9 @@ namespace ts {
}
switch (node.kind) {
case SyntaxKind.StringLiteral:
return getFreshTypeOfLiteralOrUniqueType(getLiteralTypeForText(TypeFlags.StringLiteral, (<LiteralExpression>node).text));
return getFreshTypeOfLiteralOrUniqueType(getLiteralType((<LiteralExpression>node).text));
case SyntaxKind.NumericLiteral:
return getFreshTypeOfLiteralOrUniqueType(getLiteralTypeForText(TypeFlags.NumberLiteral, (<LiteralExpression>node).text));
return getFreshTypeOfLiteralOrUniqueType(getLiteralType(+(<LiteralExpression>node).text));
case SyntaxKind.TrueKeyword:
return trueType;
case SyntaxKind.FalseKeyword:
@@ -18587,7 +18597,7 @@ namespace ts {
// TypeScript 1.0 spec (April 2014): 8.4.3
// Accessors for the same member name must specify the same accessibility.
const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
const otherAccessor = <AccessorDeclaration>getDeclarationOfKind(getSymbolOfNode(node), otherKind);
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(node), otherKind);
if (otherAccessor) {
if ((getModifierFlags(node) & ModifierFlags.AccessibilityModifier) !== (getModifierFlags(otherAccessor) & ModifierFlags.AccessibilityModifier)) {
error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
@@ -1227,7 +1227,7 @@ namespace ts {
}
function emitPropertyDeclaration(node: Declaration) {
if (hasDynamicName(node) && !resolver.isLiteralDynamicName(<ComputedPropertyName>node.name)) {
if (hasDynamicName(node) && !resolver.isLiteralDynamicName(<ComputedPropertyName>getNameOfDeclaration(node))) {
return;
}
Copy path View file
@@ -495,6 +495,8 @@ namespace ts {
return emitMappedType(<MappedTypeNode>node);
case SyntaxKind.LiteralType:
return emitLiteralType(<LiteralTypeNode>node);
case SyntaxKind.SymbolType:
return write("symbol()");
// Binding patterns
case SyntaxKind.ObjectBindingPattern:
Copy path View file
@@ -2938,6 +2938,13 @@ namespace ts {
lateSymbol?: Symbol; // Late-bound symbol for a computed property
lateMembers?: Map<TransientSymbol>; // Late-bound members resolved during check
resolvedMembers?: SymbolTable; // Combined early- and late-bound members of a symbol
enumKind?: EnumKind; // Enum declaration classification
}
/* @internal */
export const enum EnumKind {
Numeric, // Numeric enum (each member has a TypeFlags.Enum type)
Literal // Literal enum (each member has a TypeFlags.EnumLiteral type)
}
/* @internal */
@@ -3057,7 +3064,7 @@ namespace ts {
/* @internal */
Nullable = Undefined | Null,
Literal = StringLiteral | NumberLiteral | BooleanLiteral | EnumLiteral | Unique,
Literal = StringLiteral | NumberLiteral | BooleanLiteral | Unique,
StringOrNumberLiteral = StringLiteral | NumberLiteral,
/* @internal */
StringOrNumberLiteralOrUnique = StringOrNumberLiteral | Unique,
@@ -3121,9 +3128,8 @@ namespace ts {
regularType?: UniqueType; // Regular version of the type
}
// Enum types (TypeFlags.Enum)
export interface EnumType extends Type {
memberTypes: EnumLiteralType[];
export interface StringLiteralType extends LiteralType {
value: string;
}
export interface NumberLiteralType extends LiteralType {
Copy path View file
@@ -68,7 +68,7 @@ namespace ts {
clear: () => str = "",
trackSymbol: noop,
reportInaccessibleThisError: noop,
reportIllegalExtends: noop,
reportPrivateInBaseOfClassExpression: noop,
};
}
Copy path View file
@@ -1150,7 +1150,7 @@ namespace ts {
clear: resetWriter,
trackSymbol: noop,
reportInaccessibleThisError: noop,
reportIllegalExtends: noop,
reportPrivateInBaseOfClassExpression: noop,
};
function writeIndent() {
@@ -28,7 +28,7 @@ extractIndexer({
extractIndexer({
>extractIndexer({ [E.x]: ""}) : string
>extractIndexer : <T>(p: { [n: number]: T; }) => T
>{ [E.x]: ""} : { [x: number]: string; }
>{ [E.x]: ""} : { [E.x]: string; }
[E.x]: ""
>E.x : E
@@ -28,7 +28,7 @@ extractIndexer({
extractIndexer({
>extractIndexer({ [E.x]: ""}) : string
>extractIndexer : <T>(p: { [n: number]: T; }) => T
>{ [E.x]: ""} : { [x: number]: string; }
>{ [E.x]: ""} : { [E.x]: string; }
[E.x]: ""
>E.x : E
@@ -6,8 +6,8 @@ enum E {
>member : E
}
var v = {
>v : { [x: number]: number; }
>{ [E.member]: 0} : { [x: number]: number; }
>v : { [E.member]: number; }
>{ [E.member]: 0} : { [E.member]: number; }
[E.member]: 0
>E.member : E
@@ -6,8 +6,8 @@ enum E {
>member : E
}
var v = {
>v : { [x: number]: number; }
>{ [E.member]: 0} : { [x: number]: number; }
>v : { [E.member]: number; }
>{ [E.member]: 0} : { [E.member]: number; }
[E.member]: 0
>E.member : E
You are viewing a condensed version of this merge commit. You can view the full changes here.
ProTip! Use n and p to navigate between commits in a pull request.