Merge pull request #24897 from Microsoft/restTuples

Tuples in rest parameters and spread expressions
This commit is contained in:
Anders Hejlsberg
2018-06-25 19:26:35 -07:00
committed by GitHub
124 changed files with 6268 additions and 1121 deletions
+2
View File
@@ -3606,6 +3606,8 @@ namespace ts {
case SyntaxKind.TypeLiteral:
case SyntaxKind.ArrayType:
case SyntaxKind.TupleType:
case SyntaxKind.OptionalType:
case SyntaxKind.RestType:
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
case SyntaxKind.ConditionalType:
+566 -250
View File
File diff suppressed because it is too large Load Diff
+20 -4
View File
@@ -367,10 +367,6 @@
"category": "Error",
"code": 1121
},
"A tuple type element list cannot be empty.": {
"category": "Error",
"code": 1122
},
"Variable declaration list cannot be empty.": {
"category": "Error",
"code": 1123
@@ -847,6 +843,14 @@
"category": "Error",
"code": 1255
},
"A rest element must be last in a tuple type.": {
"category": "Error",
"code": 1256
},
"A required element cannot follow an optional element.": {
"category": "Error",
"code": 1257
},
"'with' statements are not allowed in an async function block.": {
"category": "Error",
"code": 1300
@@ -2032,6 +2036,18 @@
"category": "Error",
"code": 2571
},
"Rest signatures are incompatible.": {
"category": "Error",
"code": 2572
},
"Property '{0}' is incompatible with rest element type.": {
"category": "Error",
"code": 2573
},
"A rest element type must be an array type.": {
"category": "Error",
"code": 2574
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
+10 -2
View File
@@ -659,6 +659,8 @@ namespace ts {
return emitArrayType(<ArrayTypeNode>node);
case SyntaxKind.TupleType:
return emitTupleType(<TupleTypeNode>node);
case SyntaxKind.OptionalType:
return emitOptionalType(<OptionalTypeNode>node);
case SyntaxKind.UnionType:
return emitUnionType(<UnionTypeNode>node);
case SyntaxKind.IntersectionType:
@@ -695,8 +697,9 @@ namespace ts {
return emitJSDocNonNullableType(node as JSDocNonNullableType);
case SyntaxKind.JSDocOptionalType:
return emitJSDocOptionalType(node as JSDocOptionalType);
case SyntaxKind.RestType:
case SyntaxKind.JSDocVariadicType:
return emitJSDocVariadicType(node as JSDocVariadicType);
return emitRestOrJSDocVariadicType(node as RestTypeNode | JSDocVariadicType);
// Binding patterns
case SyntaxKind.ObjectBindingPattern:
@@ -1304,7 +1307,7 @@ namespace ts {
writePunctuation("]");
}
function emitJSDocVariadicType(node: JSDocVariadicType) {
function emitRestOrJSDocVariadicType(node: RestTypeNode | JSDocVariadicType) {
write("...");
emit(node.type);
}
@@ -1315,6 +1318,11 @@ namespace ts {
writePunctuation("]");
}
function emitOptionalType(node: OptionalTypeNode) {
emit(node.type);
write("?");
}
function emitUnionType(node: UnionTypeNode) {
emitList(node, node.types, ListFormat.UnionTypeConstituents);
}
+25 -1
View File
@@ -745,12 +745,36 @@ namespace ts {
return node;
}
export function updateTypleTypeNode(node: TupleTypeNode, elementTypes: ReadonlyArray<TypeNode>) {
export function updateTupleTypeNode(node: TupleTypeNode, elementTypes: ReadonlyArray<TypeNode>) {
return node.elementTypes !== elementTypes
? updateNode(createTupleTypeNode(elementTypes), node)
: node;
}
export function createOptionalTypeNode(type: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.OptionalType) as OptionalTypeNode;
node.type = parenthesizeArrayTypeMember(type);
return node;
}
export function updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode {
return node.type !== type
? updateNode(createOptionalTypeNode(type), node)
: node;
}
export function createRestTypeNode(type: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.RestType) as RestTypeNode;
node.type = type;
return node;
}
export function updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode {
return node.type !== type
? updateNode(createRestTypeNode(type), node)
: node;
}
export function createUnionTypeNode(types: ReadonlyArray<TypeNode>): UnionTypeNode {
return <UnionTypeNode>createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, types);
}
+25 -13
View File
@@ -445,19 +445,17 @@ namespace ts {
case SyntaxKind.JsxClosingElement:
return visitNode(cbNode, (<JsxClosingElement>node).tagName);
case SyntaxKind.OptionalType:
case SyntaxKind.RestType:
case SyntaxKind.JSDocTypeExpression:
return visitNode(cbNode, (<JSDocTypeExpression>node).type);
case SyntaxKind.JSDocNonNullableType:
return visitNode(cbNode, (<JSDocNonNullableType>node).type);
case SyntaxKind.JSDocNullableType:
return visitNode(cbNode, (<JSDocNullableType>node).type);
case SyntaxKind.JSDocOptionalType:
return visitNode(cbNode, (<JSDocOptionalType>node).type);
case SyntaxKind.JSDocVariadicType:
return visitNode(cbNode, (<OptionalTypeNode | RestTypeNode | JSDocTypeExpression | JSDocTypeReferencingNode>node).type);
case SyntaxKind.JSDocFunctionType:
return visitNodes(cbNode, cbNodes, (<JSDocFunctionType>node).parameters) ||
visitNode(cbNode, (<JSDocFunctionType>node).type);
case SyntaxKind.JSDocVariadicType:
return visitNode(cbNode, (<JSDocVariadicType>node).type);
case SyntaxKind.JSDocComment:
return visitNodes(cbNode, cbNodes, (<JSDoc>node).tags);
case SyntaxKind.JSDocParameterTag:
@@ -2289,7 +2287,7 @@ namespace ts {
function parseJSDocAllType(postFixEquals: boolean): JSDocAllType | JSDocOptionalType {
const result = createNode(SyntaxKind.JSDocAllType) as JSDocAllType;
if (postFixEquals) {
return createJSDocPostfixType(SyntaxKind.JSDocOptionalType, result) as JSDocOptionalType;
return createPostfixType(SyntaxKind.JSDocOptionalType, result) as JSDocOptionalType;
}
else {
nextToken();
@@ -2367,7 +2365,7 @@ namespace ts {
type = finishNode(variadic);
}
if (token() === SyntaxKind.EqualsToken) {
return createJSDocPostfixType(SyntaxKind.JSDocOptionalType, type);
return createPostfixType(SyntaxKind.JSDocOptionalType, type);
}
return type;
}
@@ -2775,9 +2773,23 @@ namespace ts {
return finishNode(node);
}
function parseTupleElementType() {
const pos = getNodePos();
if (parseOptional(SyntaxKind.DotDotDotToken)) {
const node = <RestTypeNode>createNode(SyntaxKind.RestType, pos);
node.type = parseType();
return finishNode(node);
}
const type = parseType();
if (!(contextFlags & NodeFlags.JSDoc) && type.kind === SyntaxKind.JSDocNullableType && type.pos === (<JSDocNullableType>type).type.pos) {
type.kind = SyntaxKind.OptionalType;
}
return type;
}
function parseTupleType(): TupleTypeNode {
const node = <TupleTypeNode>createNode(SyntaxKind.TupleType);
node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
return finishNode(node);
}
@@ -2960,14 +2972,14 @@ namespace ts {
while (!scanner.hasPrecedingLineBreak()) {
switch (token()) {
case SyntaxKind.ExclamationToken:
type = createJSDocPostfixType(SyntaxKind.JSDocNonNullableType, type);
type = createPostfixType(SyntaxKind.JSDocNonNullableType, type);
break;
case SyntaxKind.QuestionToken:
// If not in JSDoc and next token is start of a type we have a conditional type
if (!(contextFlags & NodeFlags.JSDoc) && lookAhead(nextTokenIsStartOfType)) {
return type;
}
type = createJSDocPostfixType(SyntaxKind.JSDocNullableType, type);
type = createPostfixType(SyntaxKind.JSDocNullableType, type);
break;
case SyntaxKind.OpenBracketToken:
parseExpected(SyntaxKind.OpenBracketToken);
@@ -2992,9 +3004,9 @@ namespace ts {
return type;
}
function createJSDocPostfixType(kind: SyntaxKind, type: TypeNode) {
function createPostfixType(kind: SyntaxKind, type: TypeNode) {
nextToken();
const postfix = createNode(kind, type.pos) as JSDocOptionalType | JSDocNonNullableType | JSDocNullableType;
const postfix = createNode(kind, type.pos) as OptionalTypeNode | JSDocOptionalType | JSDocNonNullableType | JSDocNullableType;
postfix.type = type;
return finishNode(postfix);
}
+2
View File
@@ -380,6 +380,8 @@ namespace ts {
case SyntaxKind.ArrayType:
case SyntaxKind.TupleType:
case SyntaxKind.OptionalType:
case SyntaxKind.RestType:
case SyntaxKind.TypeLiteral:
case SyntaxKind.TypePredicate:
case SyntaxKind.TypeParameter:
+32 -2
View File
@@ -225,6 +225,8 @@ namespace ts {
TypeLiteral,
ArrayType,
TupleType,
OptionalType,
RestType,
UnionType,
IntersectionType,
ConditionalType,
@@ -269,6 +271,7 @@ namespace ts {
AsExpression,
NonNullExpression,
MetaProperty,
SyntheticExpression,
// Misc
TemplateSpan,
@@ -1101,6 +1104,16 @@ namespace ts {
elementTypes: NodeArray<TypeNode>;
}
export interface OptionalTypeNode extends TypeNode {
kind: SyntaxKind.OptionalType;
type: TypeNode;
}
export interface RestTypeNode extends TypeNode {
kind: SyntaxKind.RestType;
type: TypeNode;
}
export type UnionOrIntersectionTypeNode = UnionTypeNode | IntersectionTypeNode;
export interface UnionTypeNode extends TypeNode {
@@ -1288,6 +1301,12 @@ namespace ts {
expression?: Expression;
}
export interface SyntheticExpression extends Expression {
kind: SyntaxKind.SyntheticExpression;
isSpread: boolean;
type: Type;
}
// see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression
export type ExponentiationOperator
= SyntaxKind.AsteriskAsteriskToken
@@ -3521,14 +3540,15 @@ namespace ts {
ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s)
ContainsStatic = 1 << 9, // Synthetic property with static constituent(s)
Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name
ReverseMapped = 1 << 11, // property of reverse-inferred homomorphic mapped type.
ReverseMapped = 1 << 11, // Property of reverse-inferred homomorphic mapped type
OptionalParameter = 1 << 12, // Optional parameter
RestParameter = 1 << 13, // Rest parameter
Synthetic = SyntheticProperty | SyntheticMethod
}
/* @internal */
export interface TransientSymbol extends Symbol, SymbolLinks {
checkFlags: CheckFlags;
isRestParameter?: boolean;
}
/* @internal */
@@ -3857,6 +3877,16 @@ namespace ts {
variances?: Variance[]; // Variance of each type parameter
}
export interface TupleType extends GenericType {
minLength: number;
hasRestElement: boolean;
associatedNames?: __String[];
}
export interface TupleTypeReference extends TypeReference {
target: TupleType;
}
export interface UnionOrIntersectionType extends Type {
types: Type[]; // Constituent types
/* @internal */
+9 -1
View File
@@ -372,9 +372,17 @@ namespace ts {
visitNode((<ArrayTypeNode>node).elementType, visitor, isTypeNode));
case SyntaxKind.TupleType:
return updateTypleTypeNode((<TupleTypeNode>node),
return updateTupleTypeNode((<TupleTypeNode>node),
nodesVisitor((<TupleTypeNode>node).elementTypes, visitor, isTypeNode));
case SyntaxKind.OptionalType:
return updateOptionalTypeNode((<OptionalTypeNode>node),
visitNode((<OptionalTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.RestType:
return updateRestTypeNode((<RestTypeNode>node),
visitNode((<RestTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.UnionType:
return updateUnionTypeNode(<UnionTypeNode>node,
nodesVisitor((<UnionTypeNode>node).types, visitor, isTypeNode));