Skip to content

Commit e08d030

Browse files
committed
Merge branch 'main' into baselining2
2 parents 8ec97c1 + f654f18 commit e08d030

File tree

528 files changed

+89760
-1570
lines changed

Some content is hidden

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

528 files changed

+89760
-1570
lines changed

scripts/build/options.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module.exports = minimist(process.argv.slice(2), {
3131
reporter: process.env.reporter || process.env.r,
3232
lint: process.env.lint || true,
3333
fix: process.env.fix || process.env.f,
34-
workers: process.env.workerCount || os.cpus().length,
34+
workers: process.env.workerCount || ((os.cpus().length - (process.env.CI ? 0 : 1)) || 1),
3535
failed: false,
3636
keepFailed: false,
3737
lkg: true,

src/compiler/checker.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,7 +5262,18 @@ namespace ts {
52625262
if (!nodeIsSynthesized(node) && getParseTreeNode(node) === node) {
52635263
return node;
52645264
}
5265-
return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext)), node);
5265+
return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext, deepCloneOrReuseNodes)), node);
5266+
}
5267+
5268+
function deepCloneOrReuseNodes<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
5269+
function deepCloneOrReuseNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
5270+
function deepCloneOrReuseNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined {
5271+
if (nodes && nodes.length === 0) {
5272+
// Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements,
5273+
// which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding.
5274+
return setTextRange(factory.createNodeArray<T>(/*nodes*/ undefined, nodes.hasTrailingComma), nodes);
5275+
}
5276+
return visitNodes(nodes, visitor, test, start, count);
52665277
}
52675278
}
52685279

@@ -15849,7 +15860,11 @@ namespace ts {
1584915860
}
1585015861

1585115862
function isSingletonTupleType(node: TypeNode) {
15852-
return isTupleTypeNode(node) && length(node.elements) === 1 && !isOptionalTypeNode(node.elements[0]) && !isRestTypeNode(node.elements[0]);
15863+
return isTupleTypeNode(node) &&
15864+
length(node.elements) === 1 &&
15865+
!isOptionalTypeNode(node.elements[0]) &&
15866+
!isRestTypeNode(node.elements[0]) &&
15867+
!(isNamedTupleMember(node.elements[0]) && (node.elements[0].questionToken || node.elements[0].dotDotDotToken));
1585315868
}
1585415869

1585515870
/**
@@ -20629,6 +20644,9 @@ namespace ts {
2062920644
function createMarkerType(symbol: Symbol, source: TypeParameter, target: Type) {
2063020645
const mapper = makeUnaryTypeMapper(source, target);
2063120646
const type = getDeclaredTypeOfSymbol(symbol);
20647+
if (isErrorType(type)) {
20648+
return type;
20649+
}
2063220650
const result = symbol.flags & SymbolFlags.TypeAlias ?
2063320651
getTypeAliasInstantiation(symbol, instantiateTypes(getSymbolLinks(symbol).typeParameters!, mapper)) :
2063420652
createTypeReference(type as GenericType, instantiateTypes((type as GenericType).typeParameters, mapper));
@@ -25293,6 +25311,7 @@ namespace ts {
2529325311
// a generic type without a nullable constraint and x is a generic type. This is because when both obj
2529425312
// and x are of generic types T and K, we want the resulting type to be T[K].
2529525313
return parent.kind === SyntaxKind.PropertyAccessExpression ||
25314+
parent.kind === SyntaxKind.QualifiedName ||
2529625315
parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === node ||
2529725316
parent.kind === SyntaxKind.ElementAccessExpression && (parent as ElementAccessExpression).expression === node &&
2529825317
!(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression)));
@@ -25439,7 +25458,7 @@ namespace ts {
2543925458
if (func.parameters.length >= 2 && isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
2544025459
const contextualSignature = getContextualSignature(func);
2544125460
if (contextualSignature && contextualSignature.parameters.length === 1 && signatureHasRestParameter(contextualSignature)) {
25442-
const restType = getTypeOfSymbol(contextualSignature.parameters[0]);
25461+
const restType = getReducedApparentType(getTypeOfSymbol(contextualSignature.parameters[0]));
2544325462
if (restType.flags & TypeFlags.Union && everyType(restType, isTupleType) && !isSymbolAssigned(symbol)) {
2544425463
const narrowedType = getFlowTypeOfReference(func, restType, restType, /*flowContainer*/ undefined, location.flowNode);
2544525464
const index = func.parameters.indexOf(declaration) - (getThisParameter(func) ? 1 : 0);
@@ -26891,9 +26910,14 @@ namespace ts {
2689126910
return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
2689226911
}
2689326912
// For other purposes (e.g. determining whether to produce literal types) we only
26894-
// incorporate inferences made from the return type in a function call.
26913+
// incorporate inferences made from the return type in a function call. We remove
26914+
// the 'boolean' type from the contextual type such that contextually typed boolean
26915+
// literals actually end up widening to 'boolean' (see #48363).
2689526916
if (inferenceContext.returnMapper) {
26896-
return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
26917+
const type = instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
26918+
return type.flags & TypeFlags.Union && containsType((type as UnionType).types, regularFalseType) && containsType((type as UnionType).types, regularTrueType) ?
26919+
filterType(type, t => t !== regularFalseType && t !== regularTrueType) :
26920+
type;
2689726921
}
2689826922
}
2689926923
}

src/compiler/commandLineParser.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,18 @@ namespace ts {
884884
description: Diagnostics.Allow_accessing_UMD_globals_from_modules,
885885
defaultValueDescription: false,
886886
},
887+
{
888+
name: "moduleSuffixes",
889+
type: "list",
890+
element: {
891+
name: "suffix",
892+
type: "string",
893+
},
894+
listPreserveFalsyValues: true,
895+
affectsModuleResolution: true,
896+
category: Diagnostics.Modules,
897+
description: Diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module,
898+
},
887899

888900
// Source Maps
889901
{
@@ -3192,7 +3204,7 @@ namespace ts {
31923204
if (option.type === "list") {
31933205
const listOption = option;
31943206
if (listOption.element.isFilePath || !isString(listOption.element.type)) {
3195-
return filter(map(value, v => normalizeOptionValue(listOption.element, basePath, v)), v => !!v) as CompilerOptionsValue;
3207+
return filter(map(value, v => normalizeOptionValue(listOption.element, basePath, v)), v => listOption.listPreserveFalsyValues ? true : !!v) as CompilerOptionsValue;
31963208
}
31973209
return value;
31983210
}
@@ -3233,7 +3245,7 @@ namespace ts {
32333245
}
32343246

32353247
function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: readonly any[], basePath: string, errors: Push<Diagnostic>): any[] {
3236-
return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v);
3248+
return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => option.listPreserveFalsyValues ? true : !!v);
32373249
}
32383250

32393251
/**

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5878,6 +5878,10 @@
58785878
"category": "Message",
58795879
"code": 6930
58805880
},
5881+
"List of file name suffixes to search when resolving a module." : {
5882+
"category": "Error",
5883+
"code": 6931
5884+
},
58815885

58825886
"Variable '{0}' implicitly has an '{1}' type.": {
58835887
"category": "Error",

src/compiler/emitter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,6 +2370,7 @@ namespace ts {
23702370
writeLine();
23712371
decreaseIndent();
23722372
}
2373+
emitList(node, node.members, ListFormat.PreserveLines);
23732374
writePunctuation("}");
23742375
}
23752376

src/compiler/moduleNameResolver.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,16 @@ namespace ts {
15761576

15771577
/** Return the file if it exists. */
15781578
function tryFile(fileName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
1579+
if (!state.compilerOptions.moduleSuffixes?.length) {
1580+
return tryFileLookup(fileName, onlyRecordFailures, state);
1581+
}
1582+
1583+
const ext = tryGetExtensionFromPath(fileName) ?? "";
1584+
const fileNameNoExtension = ext ? removeExtension(fileName, ext) : fileName;
1585+
return forEach(state.compilerOptions.moduleSuffixes, suffix => tryFileLookup(fileNameNoExtension + suffix + ext, onlyRecordFailures, state));
1586+
}
1587+
1588+
function tryFileLookup(fileName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
15791589
if (!onlyRecordFailures) {
15801590
if (state.host.fileExists(fileName)) {
15811591
if (state.traceEnabled) {

src/compiler/parser.ts

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,7 +2374,7 @@ namespace ts {
23742374
return createNodeArray(list, listPos);
23752375
}
23762376

2377-
function parseListElement<T extends Node>(parsingContext: ParsingContext, parseElement: () => T): T {
2377+
function parseListElement<T extends Node | undefined>(parsingContext: ParsingContext, parseElement: () => T): T {
23782378
const node = currentNode(parsingContext);
23792379
if (node) {
23802380
return consumeNode(node) as T;
@@ -2719,7 +2719,9 @@ namespace ts {
27192719
}
27202720

27212721
// Parses a comma-delimited list of elements
2722-
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray<T> {
2722+
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray<T>;
2723+
function parseDelimitedList<T extends Node | undefined>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray<NonNullable<T>> | undefined;
2724+
function parseDelimitedList<T extends Node | undefined>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray<NonNullable<T>> | undefined {
27232725
const saveParsingContext = parsingContext;
27242726
parsingContext |= 1 << kind;
27252727
const list = [];
@@ -2729,7 +2731,11 @@ namespace ts {
27292731
while (true) {
27302732
if (isListElement(kind, /*inErrorRecovery*/ false)) {
27312733
const startPos = scanner.getStartPos();
2732-
list.push(parseListElement(kind, parseElement));
2734+
const result = parseListElement(kind, parseElement);
2735+
if (!result) {
2736+
return undefined;
2737+
}
2738+
list.push(result as NonNullable<T>);
27332739
commaStart = scanner.getTokenPos();
27342740

27352741
if (parseOptional(SyntaxKind.CommaToken)) {
@@ -3239,15 +3245,24 @@ namespace ts {
32393245
return name;
32403246
}
32413247

3242-
function parseParameterInOuterAwaitContext() {
3243-
return parseParameterWorker(/*inOuterAwaitContext*/ true);
3248+
function isParameterNameStart() {
3249+
// Be permissive about await and yield by calling isBindingIdentifier instead of isIdentifier; disallowing
3250+
// them during a speculative parse leads to many more follow-on errors than allowing the function to parse then later
3251+
// complaining about the use of the keywords.
3252+
return isBindingIdentifier() || token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken;
3253+
}
3254+
3255+
function parseParameter(inOuterAwaitContext: boolean): ParameterDeclaration {
3256+
return parseParameterWorker(inOuterAwaitContext);
32443257
}
32453258

3246-
function parseParameter(): ParameterDeclaration {
3247-
return parseParameterWorker(/*inOuterAwaitContext*/ false);
3259+
function parseParameterForSpeculation(inOuterAwaitContext: boolean): ParameterDeclaration | undefined {
3260+
return parseParameterWorker(inOuterAwaitContext, /*allowAmbiguity*/ false);
32483261
}
32493262

3250-
function parseParameterWorker(inOuterAwaitContext: boolean): ParameterDeclaration {
3263+
function parseParameterWorker(inOuterAwaitContext: boolean): ParameterDeclaration;
3264+
function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity: false): ParameterDeclaration | undefined;
3265+
function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity = true): ParameterDeclaration | undefined {
32513266
const pos = getNodePos();
32523267
const hasJSDoc = hasPrecedingJSDocComment();
32533268

@@ -3277,13 +3292,20 @@ namespace ts {
32773292

32783293
const savedTopLevel = topLevel;
32793294
topLevel = false;
3295+
32803296
const modifiers = parseModifiers();
3297+
const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
3298+
3299+
if (!allowAmbiguity && !isParameterNameStart()) {
3300+
return undefined;
3301+
}
3302+
32813303
const node = withJSDoc(
32823304
finishNode(
32833305
factory.createParameterDeclaration(
32843306
decorators,
32853307
modifiers,
3286-
parseOptionalToken(SyntaxKind.DotDotDotToken),
3308+
dotDotDotToken,
32873309
parseNameOfParameter(modifiers),
32883310
parseOptionalToken(SyntaxKind.QuestionToken),
32893311
parseTypeAnnotation(),
@@ -3322,7 +3344,9 @@ namespace ts {
33223344
return false;
33233345
}
33243346

3325-
function parseParametersWorker(flags: SignatureFlags) {
3347+
function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: true): NodeArray<ParameterDeclaration>;
3348+
function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: false): NodeArray<ParameterDeclaration> | undefined;
3349+
function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: boolean): NodeArray<ParameterDeclaration> | undefined {
33263350
// FormalParameters [Yield,Await]: (modified)
33273351
// [empty]
33283352
// FormalParameterList[?Yield,Await]
@@ -3344,7 +3368,7 @@ namespace ts {
33443368

33453369
const parameters = flags & SignatureFlags.JSDoc ?
33463370
parseDelimitedList(ParsingContext.JSDocParameters, parseJSDocParameter) :
3347-
parseDelimitedList(ParsingContext.Parameters, savedAwaitContext ? parseParameterInOuterAwaitContext : parseParameter);
3371+
parseDelimitedList(ParsingContext.Parameters, () => allowAmbiguity ? parseParameter(savedAwaitContext) : parseParameterForSpeculation(savedAwaitContext));
33483372

33493373
setYieldContext(savedYieldContext);
33503374
setAwaitContext(savedAwaitContext);
@@ -3370,7 +3394,7 @@ namespace ts {
33703394
return createMissingList<ParameterDeclaration>();
33713395
}
33723396

3373-
const parameters = parseParametersWorker(flags);
3397+
const parameters = parseParametersWorker(flags, /*allowAmbiguity*/ true);
33743398
parseExpected(SyntaxKind.CloseParenToken);
33753399
return parameters;
33763400
}
@@ -3463,7 +3487,7 @@ namespace ts {
34633487
}
34643488

34653489
function parseIndexSignatureDeclaration(pos: number, hasJSDoc: boolean, decorators: NodeArray<Decorator> | undefined, modifiers: NodeArray<Modifier> | undefined): IndexSignatureDeclaration {
3466-
const parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
3490+
const parameters = parseBracketedList<ParameterDeclaration>(ParsingContext.Parameters, () => parseParameter(/*inOuterAwaitContext*/ false), SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
34673491
const type = parseTypeAnnotation();
34683492
parseTypeMemberSemicolon();
34693493
const node = factory.createIndexSignature(decorators, modifiers, parameters, type);
@@ -4641,7 +4665,16 @@ namespace ts {
46414665
parameters = createMissingList<ParameterDeclaration>();
46424666
}
46434667
else {
4644-
parameters = parseParametersWorker(isAsync);
4668+
if (!allowAmbiguity) {
4669+
const maybeParameters = parseParametersWorker(isAsync, allowAmbiguity);
4670+
if (!maybeParameters) {
4671+
return undefined;
4672+
}
4673+
parameters = maybeParameters;
4674+
}
4675+
else {
4676+
parameters = parseParametersWorker(isAsync, allowAmbiguity);
4677+
}
46454678
if (!parseExpected(SyntaxKind.CloseParenToken) && !allowAmbiguity) {
46464679
return undefined;
46474680
}

src/compiler/program.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,10 @@ namespace ts {
19581958
}
19591959

19601960
function isSourceFileDefaultLibrary(file: SourceFile): boolean {
1961+
if (!file.isDeclarationFile) {
1962+
return false;
1963+
}
1964+
19611965
if (file.hasNoDefaultLib) {
19621966
return true;
19631967
}
@@ -3326,21 +3330,6 @@ namespace ts {
33263330
}
33273331

33283332
function verifyCompilerOptions() {
3329-
const isNightly = stringContains(version, "-dev") || stringContains(version, "-insiders");
3330-
if (!isNightly) {
3331-
if (getEmitModuleKind(options) === ModuleKind.Node12) {
3332-
createOptionValueDiagnostic("module", Diagnostics.Compiler_option_0_of_value_1_is_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next, "module", "node12");
3333-
}
3334-
else if (getEmitModuleKind(options) === ModuleKind.NodeNext) {
3335-
createOptionValueDiagnostic("module", Diagnostics.Compiler_option_0_of_value_1_is_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next, "module", "nodenext");
3336-
}
3337-
else if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node12) {
3338-
createOptionValueDiagnostic("moduleResolution", Diagnostics.Compiler_option_0_of_value_1_is_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next, "moduleResolution", "node12");
3339-
}
3340-
else if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext) {
3341-
createOptionValueDiagnostic("moduleResolution", Diagnostics.Compiler_option_0_of_value_1_is_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next, "moduleResolution", "nodenext");
3342-
}
3343-
}
33443333
if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) {
33453334
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
33463335
}

0 commit comments

Comments
 (0)