Skip to content

Commit 60ee5e8

Browse files
committed
Merge remote-tracking branch 'upstream/master'
* upstream/master: Support naming tuple members (microsoft#38234) LEGO: check in for master to temporary branch. fix: extract const in jsx (microsoft#37912) No contextual types from circular mapped type properties (microsoft#38653) Ensure formatter can always get a newline character (microsoft#38579) Fix debug command for Node debugging Remove mentions of runtests-browser in CONTRIBUTING.md fix(33233): add outlining for comments before property access expression regression(38485): allow using rawText property in processing a tagged template
2 parents 2f9f51b + 5f597e6 commit 60ee5e8

File tree

90 files changed

+2756
-741
lines changed

Some content is hidden

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

90 files changed

+2756
-741
lines changed

CONTRIBUTING.md

Lines changed: 203 additions & 216 deletions
Large diffs are not rendered by default.

src/compiler/checker.ts

Lines changed: 195 additions & 65 deletions
Large diffs are not rendered by default.

src/compiler/diagnosticMessages.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3517,6 +3517,22 @@
35173517
"category": "Error",
35183518
"code": 5083
35193519
},
3520+
"Tuple members must all have names or all not have names.": {
3521+
"category": "Error",
3522+
"code": 5084
3523+
},
3524+
"A tuple member cannot be both optional and rest.": {
3525+
"category": "Error",
3526+
"code": 5085
3527+
},
3528+
"A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type.": {
3529+
"category": "Error",
3530+
"code": 5086
3531+
},
3532+
"A labeled tuple element is declared as rest with a `...` before the name, rather than before the type.": {
3533+
"category": "Error",
3534+
"code": 5087
3535+
},
35203536

35213537
"Generates a sourcemap for each corresponding '.d.ts' file.": {
35223538
"category": "Message",
@@ -5677,6 +5693,14 @@
56775693
"category": "Message",
56785694
"code": 95116
56795695
},
5696+
"Move labeled tuple element modifiers to labels": {
5697+
"category": "Message",
5698+
"code": 95117
5699+
},
5700+
"Convert overload list to single signature": {
5701+
"category": "Message",
5702+
"code": 95118
5703+
},
56805704

56815705
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
56825706
"category": "Error",

src/compiler/emitter.ts

Lines changed: 16 additions & 4 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,19 @@ 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.dotDotDotToken);
2112+
emit(node.name);
2113+
emit(node.questionToken);
2114+
emitTokenWithComment(SyntaxKind.ColonToken, node.name.end, writePunctuation, node);
2115+
writeSpace();
2116+
emit(node.type);
21052117
}
21062118

21072119
function emitOptionalType(node: OptionalTypeNode) {
@@ -4968,7 +4980,7 @@ namespace ts {
49684980
}
49694981

49704982
function emitLeadingSynthesizedComment(comment: SynthesizedComment) {
4971-
if (comment.kind === SyntaxKind.SingleLineCommentTrivia) {
4983+
if (comment.hasLeadingNewline || comment.kind === SyntaxKind.SingleLineCommentTrivia) {
49724984
writer.writeLine();
49734985
}
49744986
writeSynthesizedComment(comment);

src/compiler/factoryPublic.ts

Lines changed: 38 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,24 @@ namespace ts {
934934
: node;
935935
}
936936

937+
export function createNamedTupleMember(dotDotDotToken: Token<SyntaxKind.DotDotDotToken> | undefined, name: Identifier, questionToken: Token<SyntaxKind.QuestionToken> | undefined, type: TypeNode) {
938+
const node = <NamedTupleMember>createSynthesizedNode(SyntaxKind.NamedTupleMember);
939+
node.dotDotDotToken = dotDotDotToken;
940+
node.name = name;
941+
node.questionToken = questionToken;
942+
node.type = type;
943+
return node;
944+
}
945+
946+
export function updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: Token<SyntaxKind.DotDotDotToken> | undefined, name: Identifier, questionToken: Token<SyntaxKind.QuestionToken> | undefined, type: TypeNode) {
947+
return node.dotDotDotToken !== dotDotDotToken
948+
|| node.name !== name
949+
|| node.questionToken !== questionToken
950+
|| node.type !== type
951+
? updateNode(createNamedTupleMember(dotDotDotToken, name, questionToken, type), node)
952+
: node;
953+
}
954+
937955
export function createThisTypeNode() {
938956
return <ThisTypeNode>createSynthesizedNode(SyntaxKind.ThisType);
939957
}
@@ -2616,6 +2634,21 @@ namespace ts {
26162634
return node;
26172635
}
26182636

2637+
2638+
/* @internal */
2639+
export function createJSDocVariadicType(type: TypeNode): JSDocVariadicType {
2640+
const node = createSynthesizedNode(SyntaxKind.JSDocVariadicType) as JSDocVariadicType;
2641+
node.type = type;
2642+
return node;
2643+
}
2644+
2645+
/* @internal */
2646+
export function updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType {
2647+
return node.type !== type
2648+
? updateNode(createJSDocVariadicType(type), node)
2649+
: node;
2650+
}
2651+
26192652
// JSX
26202653

26212654
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);
@@ -3066,9 +3071,33 @@ namespace ts {
30663071
return type;
30673072
}
30683073

3074+
function isNextTokenColonOrQuestionColon() {
3075+
return nextToken() === SyntaxKind.ColonToken || (token() === SyntaxKind.QuestionToken && nextToken() === SyntaxKind.ColonToken);
3076+
}
3077+
3078+
function isTupleElementName() {
3079+
if (token() === SyntaxKind.DotDotDotToken) {
3080+
return tokenIsIdentifierOrKeyword(nextToken()) && isNextTokenColonOrQuestionColon();
3081+
}
3082+
return tokenIsIdentifierOrKeyword(token()) && isNextTokenColonOrQuestionColon();
3083+
}
3084+
3085+
function parseTupleElementNameOrTupleElementType() {
3086+
if (lookAhead(isTupleElementName)) {
3087+
const node = <NamedTupleMember>createNode(SyntaxKind.NamedTupleMember);
3088+
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
3089+
node.name = parseIdentifierName();
3090+
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
3091+
parseExpected(SyntaxKind.ColonToken);
3092+
node.type = parseTupleElementType();
3093+
return addJSDocComment(finishNode(node));
3094+
}
3095+
return parseTupleElementType();
3096+
}
3097+
30693098
function parseTupleType(): TupleTypeNode {
30703099
const node = <TupleTypeNode>createNode(SyntaxKind.TupleType);
3071-
node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
3100+
node.elements = parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
30723101
return finishNode(node);
30733102
}
30743103

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/transformers/taggedTemplate.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,21 @@ namespace ts {
7373
*
7474
* @param node The ES6 template literal.
7575
*/
76-
function getRawLiteral(node: LiteralLikeNode, currentSourceFile: SourceFile) {
76+
function getRawLiteral(node: TemplateLiteralLikeNode, currentSourceFile: SourceFile) {
7777
// Find original source text, since we need to emit the raw strings of the tagged template.
7878
// The raw strings contain the (escaped) strings of what the user wrote.
7979
// Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
80-
let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
80+
let text = node.rawText;
81+
if (text === undefined) {
82+
text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
8183

82-
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
83-
// thus we need to remove those characters.
84-
// First template piece starts with "`", others with "}"
85-
// Last template piece ends with "`", others with "${"
86-
const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail;
87-
text = text.substring(1, text.length - (isLast ? 1 : 2));
84+
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
85+
// thus we need to remove those characters.
86+
// First template piece starts with "`", others with "}"
87+
// Last template piece ends with "`", others with "${"
88+
const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail;
89+
text = text.substring(1, text.length - (isLast ? 1 : 2));
90+
}
8891

8992
// Newline normalization:
9093
// ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's

src/compiler/types.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ namespace ts {
329329
IndexedAccessType,
330330
MappedType,
331331
LiteralType,
332+
NamedTupleMember,
332333
ImportType,
333334
// Binding patterns
334335
ObjectBindingPattern,
@@ -708,6 +709,7 @@ namespace ts {
708709
| ConstructorTypeNode
709710
| JSDocFunctionType
710711
| ExportDeclaration
712+
| NamedTupleMember
711713
| EndOfFileToken;
712714

713715
export type HasType =
@@ -1282,7 +1284,15 @@ namespace ts {
12821284

12831285
export interface TupleTypeNode extends TypeNode {
12841286
kind: SyntaxKind.TupleType;
1285-
elementTypes: NodeArray<TypeNode>;
1287+
elements: NodeArray<TypeNode | NamedTupleMember>;
1288+
}
1289+
1290+
export interface NamedTupleMember extends TypeNode, JSDocContainer, Declaration {
1291+
kind: SyntaxKind.NamedTupleMember;
1292+
dotDotDotToken?: Token<SyntaxKind.DotDotDotToken>;
1293+
name: Identifier;
1294+
questionToken?: Token<SyntaxKind.QuestionToken>;
1295+
type: TypeNode;
12861296
}
12871297

12881298
export interface OptionalTypeNode extends TypeNode {
@@ -1486,6 +1496,7 @@ namespace ts {
14861496
kind: SyntaxKind.SyntheticExpression;
14871497
isSpread: boolean;
14881498
type: Type;
1499+
tupleNameSource?: ParameterDeclaration | NamedTupleMember;
14891500
}
14901501

14911502
// see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression
@@ -2598,6 +2609,7 @@ namespace ts {
25982609
text: string;
25992610
pos: -1;
26002611
end: -1;
2612+
hasLeadingNewline?: boolean;
26012613
}
26022614

26032615
// represents a top level: { type } expression in a JSDoc comment.
@@ -3506,7 +3518,7 @@ namespace ts {
35063518
*/
35073519
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
35083520
/* @internal */ getResolvedSignatureForSignatureHelp(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
3509-
/* @internal */ getExpandedParameters(sig: Signature): readonly Symbol[];
3521+
/* @internal */ getExpandedParameters(sig: Signature): readonly (readonly Symbol[])[];
35103522
/* @internal */ hasEffectiveRestParameter(sig: Signature): boolean;
35113523
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
35123524
isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined;
@@ -4161,6 +4173,7 @@ namespace ts {
41614173
cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target
41624174
typeOnlyDeclaration?: TypeOnlyCompatibleAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs
41634175
isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor
4176+
tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label
41644177
}
41654178

41664179
/* @internal */
@@ -4631,7 +4644,7 @@ namespace ts {
46314644
minLength: number;
46324645
hasRestElement: boolean;
46334646
readonly: boolean;
4634-
associatedNames?: __String[];
4647+
labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[];
46354648
}
46364649

46374650
export interface TupleTypeReference extends TypeReference {
@@ -6580,7 +6593,8 @@ namespace ts {
65806593
SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings,
65816594
MultiLineTypeLiteralMembers = MultiLine | Indented | OptionalIfEmpty,
65826595

6583-
TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
6596+
SingleLineTupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
6597+
MultiLineTupleTypeElements = CommaDelimited | Indented | SpaceBetweenSiblings | MultiLine,
65846598
UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine,
65856599
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
65866600
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty,

src/compiler/visitorPublic.ts

Lines changed: 9 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,14 @@ namespace ts {
517517
(<ImportTypeNode>node).isTypeOf
518518
);
519519

520+
case SyntaxKind.NamedTupleMember:
521+
return updateNamedTupleMember(<NamedTupleMember>node,
522+
visitNode((<NamedTupleMember>node).dotDotDotToken, visitor, isToken),
523+
visitNode((<NamedTupleMember>node).name, visitor, isIdentifier),
524+
visitNode((<NamedTupleMember>node).questionToken, visitor, isToken),
525+
visitNode((<NamedTupleMember>node).type, visitor, isTypeNode),
526+
);
527+
520528
case SyntaxKind.ParenthesizedType:
521529
return updateParenthesizedType(<ParenthesizedTypeNode>node,
522530
visitNode((<ParenthesizedTypeNode>node).type, visitor, isTypeNode));

src/harness/fourslashImpl.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,12 @@ namespace FourSlash {
515515
}
516516
}
517517

518+
public verifyOrganizeImports(newContent: string) {
519+
const changes = this.languageService.organizeImports({ fileName: this.activeFile.fileName, type: "file" }, this.formatCodeSettings, ts.emptyOptions);
520+
this.applyChanges(changes);
521+
this.verifyFileContent(this.activeFile.fileName, newContent);
522+
}
523+
518524
private raiseError(message: string): never {
519525
throw new Error(this.messageAtLastKnownMarker(message));
520526
}

src/harness/fourslashInterfaceImpl.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,10 @@ namespace FourSlashInterface {
560560
public noMoveToNewFile(): void {
561561
this.state.noMoveToNewFile();
562562
}
563+
564+
public organizeImports(newContent: string) {
565+
this.state.verifyOrganizeImports(newContent);
566+
}
563567
}
564568

565569
export class Edit {

0 commit comments

Comments
 (0)