Skip to content

Commit bf7e5d6

Browse files
committed
Initial draft of named tuple members
1 parent 35c1ba6 commit bf7e5d6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+885
-427
lines changed

src/compiler/checker.ts

Lines changed: 71 additions & 22 deletions
Large diffs are not rendered by default.

src/compiler/diagnosticMessages.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3517,6 +3517,18 @@
35173517
"category": "Error",
35183518
"code": 5083
35193519
},
3520+
"Tuple members must all have names or not have names.": {
3521+
"category": "Error",
3522+
"code": 5084
3523+
},
3524+
"Tuple members express optionality with a trailing question mark on the type, a question mark on the member name is invalid.": {
3525+
"category": "Error",
3526+
"code": 5085
3527+
},
3528+
"Rest tuple members are declared with a `...` on the type. A `...` on the name is invalid.": {
3529+
"category": "Error",
3530+
"code": 5086
3531+
},
35203532

35213533
"Generates a sourcemap for each corresponding '.d.ts' file.": {
35223534
"category": "Message",

src/compiler/emitter.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,8 @@ namespace ts {
13701370
case SyntaxKind.RestType:
13711371
case SyntaxKind.JSDocVariadicType:
13721372
return emitRestOrJSDocVariadicType(node as RestTypeNode | JSDocVariadicType);
1373+
case SyntaxKind.NamedTupleMember:
1374+
return emitNamedTupleMember(node as NamedTupleMember);
13731375

13741376
// Binding patterns
13751377
case SyntaxKind.ObjectBindingPattern:
@@ -2099,9 +2101,17 @@ namespace ts {
20992101
}
21002102

21012103
function emitTupleType(node: TupleTypeNode) {
2102-
writePunctuation("[");
2103-
emitList(node, node.elementTypes, ListFormat.TupleTypeElements);
2104-
writePunctuation("]");
2104+
emitTokenWithComment(SyntaxKind.OpenBracketToken, node.pos, writePunctuation, node);
2105+
const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTupleTypeElements : ListFormat.MultiLineTupleTypeElements;
2106+
emitList(node, node.elements, flags | ListFormat.NoSpaceIfEmpty);
2107+
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.elements.end, writePunctuation, node);
2108+
}
2109+
2110+
function emitNamedTupleMember(node: NamedTupleMember) {
2111+
emit(node.name);
2112+
emitTokenWithComment(SyntaxKind.ColonToken, node.name.end, writePunctuation, node);
2113+
writeSpace();
2114+
emit(node.type);
21052115
}
21062116

21072117
function emitOptionalType(node: OptionalTypeNode) {

src/compiler/factoryPublic.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -810,15 +810,15 @@ namespace ts {
810810
: node;
811811
}
812812

813-
export function createTupleTypeNode(elementTypes: readonly TypeNode[]) {
813+
export function createTupleTypeNode(elements: readonly (TypeNode | NamedTupleMember)[]) {
814814
const node = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode;
815-
node.elementTypes = createNodeArray(elementTypes);
815+
node.elements = createNodeArray(elements);
816816
return node;
817817
}
818818

819-
export function updateTupleTypeNode(node: TupleTypeNode, elementTypes: readonly TypeNode[]) {
820-
return node.elementTypes !== elementTypes
821-
? updateNode(createTupleTypeNode(elementTypes), node)
819+
export function updateTupleTypeNode(node: TupleTypeNode, elements: readonly (TypeNode | NamedTupleMember)[]) {
820+
return node.elements !== elements
821+
? updateNode(createTupleTypeNode(elements), node)
822822
: node;
823823
}
824824

@@ -934,6 +934,20 @@ namespace ts {
934934
: node;
935935
}
936936

937+
export function createNamedTupleMember(name: Identifier, type: TypeNode) {
938+
const node = <NamedTupleMember>createSynthesizedNode(SyntaxKind.NamedTupleMember);
939+
node.name = name;
940+
node.type = type;
941+
return node;
942+
}
943+
944+
export function updateNamedTupleMember(node: NamedTupleMember, name: Identifier, type: TypeNode) {
945+
return node.name !== name
946+
|| node.type !== type
947+
? updateNode(createNamedTupleMember(name, type), node)
948+
: node;
949+
}
950+
937951
export function createThisTypeNode() {
938952
return <ThisTypeNode>createSynthesizedNode(SyntaxKind.ThisType);
939953
}
@@ -2525,6 +2539,21 @@ namespace ts {
25252539
return node;
25262540
}
25272541

2542+
2543+
/* @internal */
2544+
export function createJSDocVariadicType(type: TypeNode): JSDocVariadicType {
2545+
const node = createSynthesizedNode(SyntaxKind.JSDocVariadicType) as JSDocVariadicType;
2546+
node.type = type;
2547+
return node;
2548+
}
2549+
2550+
/* @internal */
2551+
export function updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType {
2552+
return node.type !== type
2553+
? updateNode(createJSDocVariadicType(type), node)
2554+
: node;
2555+
}
2556+
25282557
// JSX
25292558

25302559
export function createJsxElement(openingElement: JsxOpeningElement, children: readonly JsxChild[], closingElement: JsxClosingElement) {

src/compiler/parser.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ namespace ts {
179179
case SyntaxKind.ArrayType:
180180
return visitNode(cbNode, (<ArrayTypeNode>node).elementType);
181181
case SyntaxKind.TupleType:
182-
return visitNodes(cbNode, cbNodes, (<TupleTypeNode>node).elementTypes);
182+
return visitNodes(cbNode, cbNodes, (<TupleTypeNode>node).elements);
183183
case SyntaxKind.UnionType:
184184
case SyntaxKind.IntersectionType:
185185
return visitNodes(cbNode, cbNodes, (<UnionOrIntersectionTypeNode>node).types);
@@ -207,6 +207,11 @@ namespace ts {
207207
visitNode(cbNode, (<MappedTypeNode>node).type);
208208
case SyntaxKind.LiteralType:
209209
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
210+
case SyntaxKind.NamedTupleMember:
211+
return visitNode(cbNode, (<NamedTupleMember>node).dotDotDotToken) ||
212+
visitNode(cbNode, (<NamedTupleMember>node).name) ||
213+
visitNode(cbNode, (<NamedTupleMember>node).questionToken) ||
214+
visitNode(cbNode, (<NamedTupleMember>node).type);
210215
case SyntaxKind.ObjectBindingPattern:
211216
case SyntaxKind.ArrayBindingPattern:
212217
return visitNodes(cbNode, cbNodes, (<BindingPattern>node).elements);
@@ -3056,9 +3061,33 @@ namespace ts {
30563061
return type;
30573062
}
30583063

3064+
function isNextTokenColonOrQuestionColon() {
3065+
return nextToken() === SyntaxKind.ColonToken || (token() === SyntaxKind.QuestionToken && nextToken() === SyntaxKind.ColonToken);
3066+
}
3067+
3068+
function isTupleElementName() {
3069+
if (token() === SyntaxKind.DotDotDotToken) {
3070+
return tokenIsIdentifierOrKeyword(nextToken()) && isNextTokenColonOrQuestionColon();
3071+
}
3072+
return tokenIsIdentifierOrKeyword(token()) && isNextTokenColonOrQuestionColon();
3073+
}
3074+
3075+
function parseTupleElementNameOrTupleElementType() {
3076+
if (lookAhead(isTupleElementName)) {
3077+
const node = <NamedTupleMember>createNode(SyntaxKind.NamedTupleMember);
3078+
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
3079+
node.name = parseIdentifierName();
3080+
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
3081+
parseExpected(SyntaxKind.ColonToken);
3082+
node.type = parseTupleElementType();
3083+
return addJSDocComment(finishNode(node));
3084+
}
3085+
return parseTupleElementType();
3086+
}
3087+
30593088
function parseTupleType(): TupleTypeNode {
30603089
const node = <TupleTypeNode>createNode(SyntaxKind.TupleType);
3061-
node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
3090+
node.elements = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
30623091
return finishNode(node);
30633092
}
30643093

src/compiler/transformers/declarations.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,10 @@ namespace ts {
10181018
}
10191019
}
10201020

1021+
if (isTupleTypeNode(input) && (getLineAndCharacterOfPosition(currentSourceFile, input.pos).line === getLineAndCharacterOfPosition(currentSourceFile, input.end).line)) {
1022+
setEmitFlags(input, EmitFlags.SingleLine);
1023+
}
1024+
10211025
return cleanup(visitEachChild(input, visitDeclarationSubtree, context));
10221026

10231027
function cleanup<T extends Node>(returnValue: T | undefined): T | undefined {

src/compiler/types.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ namespace ts {
328328
IndexedAccessType,
329329
MappedType,
330330
LiteralType,
331+
NamedTupleMember,
331332
ImportType,
332333
// Binding patterns
333334
ObjectBindingPattern,
@@ -699,6 +700,7 @@ namespace ts {
699700
| ConstructorTypeNode
700701
| JSDocFunctionType
701702
| ExportDeclaration
703+
| NamedTupleMember
702704
| EndOfFileToken;
703705

704706
export type HasType =
@@ -1273,7 +1275,15 @@ namespace ts {
12731275

12741276
export interface TupleTypeNode extends TypeNode {
12751277
kind: SyntaxKind.TupleType;
1276-
elementTypes: NodeArray<TypeNode>;
1278+
elements: NodeArray<TypeNode | NamedTupleMember>;
1279+
}
1280+
1281+
export interface NamedTupleMember extends TypeNode, JSDocContainer {
1282+
kind: SyntaxKind.NamedTupleMember;
1283+
dotDotDotToken?: Token<SyntaxKind.DotDotDotToken>;
1284+
name: Identifier;
1285+
questionToken?: Token<SyntaxKind.QuestionToken>;
1286+
type: TypeNode;
12771287
}
12781288

12791289
export interface OptionalTypeNode extends TypeNode {
@@ -6573,7 +6583,8 @@ namespace ts {
65736583
SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings,
65746584
MultiLineTypeLiteralMembers = MultiLine | Indented | OptionalIfEmpty,
65756585

6576-
TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
6586+
SingleLineTupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
6587+
MultiLineTupleTypeElements = CommaDelimited | Indented | SpaceBetweenSiblings | MultiLine,
65776588
UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine,
65786589
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
65796590
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty,

src/compiler/utilities.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2702,7 +2702,10 @@ namespace ts {
27022702
}
27032703

27042704
export function walkUpParenthesizedTypes(node: Node) {
2705-
return walkUp(node, SyntaxKind.ParenthesizedType);
2705+
while (node && (node.kind === SyntaxKind.ParenthesizedType || node.kind === SyntaxKind.NamedTupleMember)) {
2706+
node = node.parent;
2707+
}
2708+
return node;
27062709
}
27072710

27082711
export function walkUpParenthesizedExpressions(node: Node) {

src/compiler/visitorPublic.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ namespace ts {
480480

481481
case SyntaxKind.TupleType:
482482
return updateTupleTypeNode((<TupleTypeNode>node),
483-
nodesVisitor((<TupleTypeNode>node).elementTypes, visitor, isTypeNode));
483+
nodesVisitor((<TupleTypeNode>node).elements, visitor, isTypeNode));
484484

485485
case SyntaxKind.OptionalType:
486486
return updateOptionalTypeNode((<OptionalTypeNode>node),
@@ -517,6 +517,12 @@ namespace ts {
517517
(<ImportTypeNode>node).isTypeOf
518518
);
519519

520+
case SyntaxKind.NamedTupleMember:
521+
return updateNamedTupleMember(<NamedTupleMember>node,
522+
visitNode((<NamedTupleMember>node).name, visitor, isIdentifierName),
523+
visitNode((<NamedTupleMember>node).type, visitor, isTypeNode),
524+
);
525+
520526
case SyntaxKind.ParenthesizedType:
521527
return updateParenthesizedType(<ParenthesizedTypeNode>node,
522528
visitNode((<ParenthesizedTypeNode>node).type, visitor, isTypeNode));

src/services/refactors/extractType.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ namespace ts.refactor {
145145
}
146146
}
147147
}
148+
149+
if (file && isTupleTypeNode(node) && (getLineAndCharacterOfPosition(file, node.pos).line === getLineAndCharacterOfPosition(file, node.end).line)) {
150+
setEmitFlags(node, EmitFlags.SingleLine);
151+
}
152+
148153
return forEachChild(node, visitor);
149154
}
150155
}

0 commit comments

Comments
 (0)