Skip to content

Commit 4eb3b6b

Browse files
committed
Merge branch 'master' into vfs
2 parents e2bbc3e + 1784e51 commit 4eb3b6b

196 files changed

Lines changed: 6923 additions & 1188 deletions

File tree

Some content is hidden

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

src/compiler/binder.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ namespace ts {
101101
HasLocals = 1 << 5,
102102
IsInterface = 1 << 6,
103103
IsObjectLiteralOrClassExpressionMethod = 1 << 7,
104+
IsInferenceContainer = 1 << 8,
104105
}
105106

106107
const binder = createBinder();
@@ -119,6 +120,7 @@ namespace ts {
119120
let parent: Node;
120121
let container: Node;
121122
let blockScopeContainer: Node;
123+
let inferenceContainer: Node;
122124
let lastContainer: Node;
123125
let seenThisKeyword: boolean;
124126

@@ -186,6 +188,7 @@ namespace ts {
186188
parent = undefined;
187189
container = undefined;
188190
blockScopeContainer = undefined;
191+
inferenceContainer = undefined;
189192
lastContainer = undefined;
190193
seenThisKeyword = false;
191194
currentFlow = undefined;
@@ -561,6 +564,13 @@ namespace ts {
561564
bindChildren(node);
562565
node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis;
563566
}
567+
else if (containerFlags & ContainerFlags.IsInferenceContainer) {
568+
const saveInferenceContainer = inferenceContainer;
569+
inferenceContainer = node;
570+
node.locals = undefined;
571+
bindChildren(node);
572+
inferenceContainer = saveInferenceContainer;
573+
}
564574
else {
565575
bindChildren(node);
566576
}
@@ -1417,6 +1427,9 @@ namespace ts {
14171427
case SyntaxKind.MappedType:
14181428
return ContainerFlags.IsContainer | ContainerFlags.HasLocals;
14191429

1430+
case SyntaxKind.ConditionalType:
1431+
return ContainerFlags.IsInferenceContainer;
1432+
14201433
case SyntaxKind.SourceFile:
14211434
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals;
14221435

@@ -2059,7 +2072,7 @@ namespace ts {
20592072
case SyntaxKind.TypePredicate:
20602073
return checkTypePredicate(node as TypePredicateNode);
20612074
case SyntaxKind.TypeParameter:
2062-
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
2075+
return bindTypeParameter(node as TypeParameterDeclaration);
20632076
case SyntaxKind.Parameter:
20642077
return bindParameter(<ParameterDeclaration>node);
20652078
case SyntaxKind.VariableDeclaration:
@@ -2576,6 +2589,23 @@ namespace ts {
25762589
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
25772590
}
25782591

2592+
function bindTypeParameter(node: TypeParameterDeclaration) {
2593+
if (node.parent.kind === SyntaxKind.InferType) {
2594+
if (inferenceContainer) {
2595+
if (!inferenceContainer.locals) {
2596+
inferenceContainer.locals = createSymbolTable();
2597+
}
2598+
declareSymbol(inferenceContainer.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
2599+
}
2600+
else {
2601+
bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, getDeclarationName(node));
2602+
}
2603+
}
2604+
else {
2605+
declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
2606+
}
2607+
}
2608+
25792609
// reachability checks
25802610

25812611
function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean {
@@ -3440,6 +3470,8 @@ namespace ts {
34403470
case SyntaxKind.TupleType:
34413471
case SyntaxKind.UnionType:
34423472
case SyntaxKind.IntersectionType:
3473+
case SyntaxKind.ConditionalType:
3474+
case SyntaxKind.InferType:
34433475
case SyntaxKind.ParenthesizedType:
34443476
case SyntaxKind.InterfaceDeclaration:
34453477
case SyntaxKind.TypeAliasDeclaration:

src/compiler/checker.ts

Lines changed: 469 additions & 150 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -439,23 +439,21 @@ namespace ts {
439439
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[];
440440
export function sameMap<T>(array: ReadonlyArray<T>, f: (x: T, i: number) => T): ReadonlyArray<T>;
441441
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[] {
442-
let result: T[];
443442
if (array) {
444443
for (let i = 0; i < array.length; i++) {
445-
if (result) {
446-
result.push(f(array[i], i));
447-
}
448-
else {
449-
const item = array[i];
450-
const mapped = f(item, i);
451-
if (item !== mapped) {
452-
result = array.slice(0, i);
453-
result.push(mapped);
444+
const item = array[i];
445+
const mapped = f(item, i);
446+
if (item !== mapped) {
447+
const result = array.slice(0, i);
448+
result.push(mapped);
449+
for (i++; i < array.length; i++) {
450+
result.push(f(array[i], i));
454451
}
452+
return result;
455453
}
456454
}
457455
}
458-
return result || array;
456+
return array;
459457
}
460458

461459
/**
@@ -1454,7 +1452,13 @@ namespace ts {
14541452

14551453
export function cast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut {
14561454
if (value !== undefined && test(value)) return value;
1457-
Debug.fail(`Invalid cast. The supplied value did not pass the test '${Debug.getFunctionName(test)}'.`);
1455+
1456+
if (value && typeof (value as any).kind === "number") {
1457+
Debug.fail(`Invalid cast. The supplied ${(ts as any).SyntaxKind[(value as any).kind]} did not pass the test '${Debug.getFunctionName(test)}'.`);
1458+
}
1459+
else {
1460+
Debug.fail(`Invalid cast. The supplied value did not pass the test '${Debug.getFunctionName(test)}'.`);
1461+
}
14581462
}
14591463

14601464
/** Does nothing. */
@@ -2772,6 +2776,10 @@ namespace ts {
27722776
this.flags = flags;
27732777
this.escapedName = name;
27742778
this.declarations = undefined;
2779+
this.valueDeclaration = undefined;
2780+
this.id = undefined;
2781+
this.mergeId = undefined;
2782+
this.parent = undefined;
27752783
}
27762784

27772785
function Type(this: Type, checker: TypeChecker, flags: TypeFlags) {
@@ -2876,6 +2884,11 @@ namespace ts {
28762884
throw e;
28772885
}
28782886

2887+
export function assertDefined<T>(value: T | null | undefined, message?: string): T {
2888+
assert(value !== undefined && value !== null, message);
2889+
return value;
2890+
}
2891+
28792892
export function assertNever(member: never, message?: string, stackCrawlMark?: AnyFunction): never {
28802893
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
28812894
}

src/compiler/declarationEmitter.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ namespace ts {
358358
}
359359
else {
360360
errorNameNode = declaration.name;
361-
const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteDefaultSymbolWithoutName |
361+
const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback |
362362
TypeFormatFlags.WriteClassExpressionAsTypeLiteral |
363363
(shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0);
364364
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer);
@@ -378,7 +378,7 @@ namespace ts {
378378
resolver.writeReturnTypeOfSignatureDeclaration(
379379
signature,
380380
enclosingDeclaration,
381-
TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName,
381+
TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral,
382382
writer);
383383
errorNameNode = undefined;
384384
}
@@ -450,6 +450,10 @@ namespace ts {
450450
return emitUnionType(<UnionTypeNode>type);
451451
case SyntaxKind.IntersectionType:
452452
return emitIntersectionType(<IntersectionTypeNode>type);
453+
case SyntaxKind.ConditionalType:
454+
return emitConditionalType(<ConditionalTypeNode>type);
455+
case SyntaxKind.InferType:
456+
return emitInferType(<InferTypeNode>type);
453457
case SyntaxKind.ParenthesizedType:
454458
return emitParenType(<ParenthesizedTypeNode>type);
455459
case SyntaxKind.TypeOperator:
@@ -545,6 +549,24 @@ namespace ts {
545549
emitSeparatedList(type.types, " & ", emitType);
546550
}
547551

552+
function emitConditionalType(node: ConditionalTypeNode) {
553+
emitType(node.checkType);
554+
write(" extends ");
555+
emitType(node.extendsType);
556+
write(" ? ");
557+
const prevEnclosingDeclaration = enclosingDeclaration;
558+
enclosingDeclaration = node.trueType;
559+
emitType(node.trueType);
560+
enclosingDeclaration = prevEnclosingDeclaration;
561+
write(" : ");
562+
emitType(node.falseType);
563+
}
564+
565+
function emitInferType(node: InferTypeNode) {
566+
write("infer ");
567+
writeTextOfNode(currentText, node.typeParameter.name);
568+
}
569+
548570
function emitParenType(type: ParenthesizedTypeNode) {
549571
write("(");
550572
emitType(type.type);
@@ -643,7 +665,7 @@ namespace ts {
643665
resolver.writeTypeOfExpression(
644666
expr,
645667
enclosingDeclaration,
646-
TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName,
668+
TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral,
647669
writer);
648670
write(";");
649671
writeLine();

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,10 @@
947947
"category": "Error",
948948
"code": 1337
949949
},
950+
"'infer' declarations are only permitted in the 'extends' clause of a conditional type.": {
951+
"category": "Error",
952+
"code": 1338
953+
},
950954

951955
"Duplicate identifier '{0}'.": {
952956
"category": "Error",

src/compiler/emitter.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,10 @@ namespace ts {
601601
return emitUnionType(<UnionTypeNode>node);
602602
case SyntaxKind.IntersectionType:
603603
return emitIntersectionType(<IntersectionTypeNode>node);
604+
case SyntaxKind.ConditionalType:
605+
return emitConditionalType(<ConditionalTypeNode>node);
606+
case SyntaxKind.InferType:
607+
return emitInferType(<InferTypeNode>node);
604608
case SyntaxKind.ParenthesizedType:
605609
return emitParenthesizedType(<ParenthesizedTypeNode>node);
606610
case SyntaxKind.ExpressionWithTypeArguments:
@@ -1191,6 +1195,28 @@ namespace ts {
11911195
emitList(node, node.types, ListFormat.IntersectionTypeConstituents);
11921196
}
11931197

1198+
function emitConditionalType(node: ConditionalTypeNode) {
1199+
emit(node.checkType);
1200+
writeSpace();
1201+
writeKeyword("extends");
1202+
writeSpace();
1203+
emit(node.extendsType);
1204+
writeSpace();
1205+
writePunctuation("?");
1206+
writeSpace();
1207+
emit(node.trueType);
1208+
writeSpace();
1209+
writePunctuation(":");
1210+
writeSpace();
1211+
emit(node.falseType);
1212+
}
1213+
1214+
function emitInferType(node: InferTypeNode) {
1215+
writeKeyword("infer");
1216+
writeSpace();
1217+
emit(node.typeParameter);
1218+
}
1219+
11941220
function emitParenthesizedType(node: ParenthesizedTypeNode) {
11951221
writePunctuation("(");
11961222
emit(node.type);

src/compiler/factory.ts

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,14 +349,15 @@ namespace ts {
349349
decorators: ReadonlyArray<Decorator> | undefined,
350350
modifiers: ReadonlyArray<Modifier> | undefined,
351351
name: string | PropertyName,
352-
questionToken: QuestionToken | undefined,
352+
questionOrExclamationToken: QuestionToken | ExclamationToken | undefined,
353353
type: TypeNode | undefined,
354354
initializer: Expression | undefined) {
355355
const node = <PropertyDeclaration>createSynthesizedNode(SyntaxKind.PropertyDeclaration);
356356
node.decorators = asNodeArray(decorators);
357357
node.modifiers = asNodeArray(modifiers);
358358
node.name = asName(name);
359-
node.questionToken = questionToken;
359+
node.questionToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.QuestionToken ? questionOrExclamationToken : undefined;
360+
node.exclamationToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.ExclamationToken ? questionOrExclamationToken : undefined;
360361
node.type = type;
361362
node.initializer = initializer;
362363
return node;
@@ -367,16 +368,17 @@ namespace ts {
367368
decorators: ReadonlyArray<Decorator> | undefined,
368369
modifiers: ReadonlyArray<Modifier> | undefined,
369370
name: string | PropertyName,
370-
questionToken: QuestionToken | undefined,
371+
questionOrExclamationToken: QuestionToken | ExclamationToken | undefined,
371372
type: TypeNode | undefined,
372373
initializer: Expression | undefined) {
373374
return node.decorators !== decorators
374375
|| node.modifiers !== modifiers
375376
|| node.name !== name
376-
|| node.questionToken !== questionToken
377+
|| node.questionToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.QuestionToken ? questionOrExclamationToken : undefined)
378+
|| node.exclamationToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === SyntaxKind.ExclamationToken ? questionOrExclamationToken : undefined)
377379
|| node.type !== type
378380
|| node.initializer !== initializer
379-
? updateNode(createProperty(decorators, modifiers, name, questionToken, type, initializer), node)
381+
? updateNode(createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node)
380382
: node;
381383
}
382384

@@ -729,6 +731,36 @@ namespace ts {
729731
: node;
730732
}
731733

734+
export function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) {
735+
const node = createSynthesizedNode(SyntaxKind.ConditionalType) as ConditionalTypeNode;
736+
node.checkType = parenthesizeConditionalTypeMember(checkType);
737+
node.extendsType = parenthesizeConditionalTypeMember(extendsType);
738+
node.trueType = trueType;
739+
node.falseType = falseType;
740+
return node;
741+
}
742+
743+
export function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) {
744+
return node.checkType !== checkType
745+
|| node.extendsType !== extendsType
746+
|| node.trueType !== trueType
747+
|| node.falseType !== falseType
748+
? updateNode(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node)
749+
: node;
750+
}
751+
752+
export function createInferTypeNode(typeParameter: TypeParameterDeclaration) {
753+
const node = <InferTypeNode>createSynthesizedNode(SyntaxKind.InferType);
754+
node.typeParameter = typeParameter;
755+
return node;
756+
}
757+
758+
export function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration) {
759+
return node.typeParameter !== typeParameter
760+
? updateNode(createInferTypeNode(typeParameter), node)
761+
: node;
762+
}
763+
732764
export function createParenthesizedType(type: TypeNode) {
733765
const node = <ParenthesizedTypeNode>createSynthesizedNode(SyntaxKind.ParenthesizedType);
734766
node.type = type;
@@ -4092,6 +4124,10 @@ namespace ts {
40924124
return expression;
40934125
}
40944126

4127+
export function parenthesizeConditionalTypeMember(member: TypeNode) {
4128+
return member.kind === SyntaxKind.ConditionalType ? createParenthesizedType(member) : member;
4129+
}
4130+
40954131
export function parenthesizeElementTypeMember(member: TypeNode) {
40964132
switch (member.kind) {
40974133
case SyntaxKind.UnionType:
@@ -4100,7 +4136,7 @@ namespace ts {
41004136
case SyntaxKind.ConstructorType:
41014137
return createParenthesizedType(member);
41024138
}
4103-
return member;
4139+
return parenthesizeConditionalTypeMember(member);
41044140
}
41054141

41064142
export function parenthesizeArrayTypeMember(member: TypeNode) {
@@ -4293,15 +4329,15 @@ namespace ts {
42934329
return emitNode && emitNode.externalHelpersModuleName;
42944330
}
42954331

4296-
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean) {
4332+
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) {
42974333
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
42984334
const externalHelpersModuleName = getExternalHelpersModuleName(node);
42994335
if (externalHelpersModuleName) {
43004336
return externalHelpersModuleName;
43014337
}
43024338

43034339
const moduleKind = getEmitModuleKind(compilerOptions);
4304-
let create = hasExportStarsToExportValues
4340+
let create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault))
43054341
&& moduleKind !== ModuleKind.System
43064342
&& moduleKind !== ModuleKind.ES2015
43074343
&& moduleKind !== ModuleKind.ESNext;

0 commit comments

Comments
 (0)