Skip to content

Commit db84122

Browse files
committed
Merge branch 'main' into cacheModuleResolution
2 parents f493901 + 35c6fbf commit db84122

File tree

286 files changed

+5280
-2144
lines changed

Some content is hidden

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

286 files changed

+5280
-2144
lines changed

package-lock.json

+108-108
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "typescript",
33
"author": "Microsoft Corp.",
44
"homepage": "https://www.typescriptlang.org/",
5-
"version": "4.8.0",
5+
"version": "4.9.0",
66
"license": "Apache-2.0",
77
"description": "TypeScript is a language for application scale JavaScript development",
88
"keywords": [

src/compiler/binder.ts

+35-12
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,9 @@ namespace ts {
850850
case SyntaxKind.BindingElement:
851851
bindBindingElementFlow(node as BindingElement);
852852
break;
853+
case SyntaxKind.Parameter:
854+
bindParameterFlow(node as ParameterDeclaration);
855+
break;
853856
case SyntaxKind.ObjectLiteralExpression:
854857
case SyntaxKind.ArrayLiteralExpression:
855858
case SyntaxKind.PropertyAssignment:
@@ -1655,20 +1658,40 @@ namespace ts {
16551658
}
16561659

16571660
function bindBindingElementFlow(node: BindingElement) {
1658-
if (isBindingPattern(node.name)) {
1659-
// When evaluating a binding pattern, the initializer is evaluated before the binding pattern, per:
1660-
// - https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-iteratorbindinginitialization
1661-
// - `BindingElement: BindingPattern Initializer?`
1662-
// - https://tc39.es/ecma262/#sec-runtime-semantics-keyedbindinginitialization
1663-
// - `BindingElement: BindingPattern Initializer?`
1664-
bind(node.dotDotDotToken);
1665-
bind(node.propertyName);
1666-
bind(node.initializer);
1667-
bind(node.name);
1661+
// When evaluating a binding pattern, the initializer is evaluated before the binding pattern, per:
1662+
// - https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-iteratorbindinginitialization
1663+
// - `BindingElement: BindingPattern Initializer?`
1664+
// - https://tc39.es/ecma262/#sec-runtime-semantics-keyedbindinginitialization
1665+
// - `BindingElement: BindingPattern Initializer?`
1666+
bind(node.dotDotDotToken);
1667+
bind(node.propertyName);
1668+
bindInitializer(node.initializer);
1669+
bind(node.name);
1670+
}
1671+
1672+
function bindParameterFlow(node: ParameterDeclaration) {
1673+
bindEach(node.modifiers);
1674+
bind(node.dotDotDotToken);
1675+
bind(node.questionToken);
1676+
bind(node.type);
1677+
bindInitializer(node.initializer);
1678+
bind(node.name);
1679+
}
1680+
1681+
// a BindingElement/Parameter does not have side effects if initializers are not evaluated and used. (see GH#49759)
1682+
function bindInitializer(node: Expression | undefined) {
1683+
if (!node) {
1684+
return;
16681685
}
1669-
else {
1670-
bindEachChild(node);
1686+
const entryFlow = currentFlow;
1687+
bind(node);
1688+
if (entryFlow === unreachableFlow || entryFlow === currentFlow) {
1689+
return;
16711690
}
1691+
const exitFlow = createBranchLabel();
1692+
addAntecedent(exitFlow, entryFlow);
1693+
addAntecedent(exitFlow, currentFlow);
1694+
currentFlow = finishFlowLabel(exitFlow);
16721695
}
16731696

16741697
function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag) {

src/compiler/checker.ts

+44-19
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ namespace ts {
14261426
function mergeSymbolTable(target: SymbolTable, source: SymbolTable, unidirectional = false) {
14271427
source.forEach((sourceSymbol, id) => {
14281428
const targetSymbol = target.get(id);
1429-
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol);
1429+
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : getMergedSymbol(sourceSymbol));
14301430
});
14311431
}
14321432

@@ -9065,10 +9065,8 @@ namespace ts {
90659065
return getReturnTypeOfSignature(getterSignature);
90669066
}
90679067
}
9068-
if (isInJSFile(declaration)) {
9069-
const type = getParameterTypeOfTypeTag(func, declaration);
9070-
if (type) return type;
9071-
}
9068+
const parameterTypeOfTypeTag = getParameterTypeOfTypeTag(func, declaration);
9069+
if (parameterTypeOfTypeTag) return parameterTypeOfTypeTag;
90729070
// Use contextual parameter type if one is available
90739071
const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
90749072
if (type) {
@@ -13117,7 +13115,14 @@ namespace ts {
1311713115
continue;
1311813116
}
1311913117
}
13120-
result.push(getSignatureFromDeclaration(decl));
13118+
// If this is a function or method declaration, get the signature from the @type tag for the sake of optional parameters.
13119+
// Exclude contextually-typed kinds because we already apply the @type tag to the context, plus applying it here to the initializer would supress checks that the two are compatible.
13120+
result.push(
13121+
(!isFunctionExpressionOrArrowFunction(decl) &&
13122+
!isObjectLiteralMethod(decl) &&
13123+
getSignatureOfTypeTag(decl)) ||
13124+
getSignatureFromDeclaration(decl)
13125+
);
1312113126
}
1312213127
return result;
1312313128
}
@@ -13152,7 +13157,7 @@ namespace ts {
1315213157
else {
1315313158
const type = signature.declaration && getEffectiveReturnTypeNode(signature.declaration);
1315413159
let jsdocPredicate: TypePredicate | undefined;
13155-
if (!type && isInJSFile(signature.declaration)) {
13160+
if (!type) {
1315613161
const jsdocSignature = getSignatureOfTypeTag(signature.declaration!);
1315713162
if (jsdocSignature && signature !== jsdocSignature) {
1315813163
jsdocPredicate = getTypePredicateOfSignature(jsdocSignature);
@@ -17470,8 +17475,7 @@ namespace ts {
1747017475
}
1747117476

1747217477
function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
17473-
return (!isFunctionDeclaration(node) || isInJSFile(node) && !!getTypeForDeclarationFromJSDocComment(node)) &&
17474-
(hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node));
17478+
return hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node);
1747517479
}
1747617480

1747717481
function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) {
@@ -17480,7 +17484,7 @@ namespace ts {
1748017484
}
1748117485

1748217486
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
17483-
return (isInJSFile(func) && isFunctionDeclaration(func) || isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) &&
17487+
return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) &&
1748417488
isContextSensitiveFunctionLikeDeclaration(func);
1748517489
}
1748617490

@@ -28163,16 +28167,31 @@ namespace ts {
2816328167
// If object literal is contextually typed by the implied type of a binding pattern, augment the result
2816428168
// type with those properties for which the binding pattern specifies a default value.
2816528169
// If the object literal is spread into another object literal, skip this step and let the top-level object
28166-
// literal handle it instead.
28167-
if (contextualTypeHasPattern && node.parent.kind !== SyntaxKind.SpreadAssignment) {
28168-
for (const prop of getPropertiesOfType(contextualType)) {
28169-
if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) {
28170-
if (!(prop.flags & SymbolFlags.Optional)) {
28171-
error(prop.valueDeclaration || (prop as TransientSymbol).bindingElement,
28172-
Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
28170+
// literal handle it instead. Note that this might require full traversal to the root pattern's parent
28171+
// as it's the guaranteed to be the common ancestor of the pattern node and the current object node.
28172+
// It's not possible to check if the immediate parent node is a spread assignment
28173+
// since the type flows in non-obvious ways through conditional expressions, IIFEs and more.
28174+
if (contextualTypeHasPattern) {
28175+
const rootPatternParent = findAncestor(contextualType.pattern!.parent, n =>
28176+
n.kind === SyntaxKind.VariableDeclaration ||
28177+
n.kind === SyntaxKind.BinaryExpression ||
28178+
n.kind === SyntaxKind.Parameter
28179+
);
28180+
const spreadOrOutsideRootObject = findAncestor(node, n =>
28181+
n === rootPatternParent ||
28182+
n.kind === SyntaxKind.SpreadAssignment
28183+
)!;
28184+
28185+
if (spreadOrOutsideRootObject.kind !== SyntaxKind.SpreadAssignment) {
28186+
for (const prop of getPropertiesOfType(contextualType)) {
28187+
if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) {
28188+
if (!(prop.flags & SymbolFlags.Optional)) {
28189+
error(prop.valueDeclaration || (prop as TransientSymbol).bindingElement,
28190+
Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
28191+
}
28192+
propertiesTable.set(prop.escapedName, prop);
28193+
propertiesArray.push(prop);
2817328194
}
28174-
propertiesTable.set(prop.escapedName, prop);
28175-
propertiesArray.push(prop);
2817628195
}
2817728196
}
2817828197
}
@@ -42533,6 +42552,12 @@ namespace ts {
4253342552
return resolveJSDocMemberName(name, /*ignoreErrors*/ false, getSymbolOfNode(container));
4253442553
}
4253542554
}
42555+
if (result && isJSDoc) {
42556+
const container = getJSDocHost(name);
42557+
if (container && isEnumMember(container) && container === result.valueDeclaration) {
42558+
return resolveEntityName(name, meaning, /*ignoreErrors*/ true, /* dontResolveAlias */ true, getSourceFileOfNode(container)) || result;
42559+
}
42560+
}
4253642561
return result;
4253742562
}
4253842563
else if (isPrivateIdentifier(name)) {

src/compiler/core.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -778,19 +778,24 @@ namespace ts {
778778
return [] as any as SortedArray<T>; // TODO: GH#19873
779779
}
780780

781-
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>, allowDuplicates?: boolean): void {
781+
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>, allowDuplicates?: boolean): boolean {
782782
if (array.length === 0) {
783783
array.push(insert);
784-
return;
784+
return true;
785785
}
786786

787787
const insertIndex = binarySearch(array, insert, identity, compare);
788788
if (insertIndex < 0) {
789789
array.splice(~insertIndex, 0, insert);
790+
return true;
790791
}
791-
else if (allowDuplicates) {
792+
793+
if (allowDuplicates) {
792794
array.splice(insertIndex, 0, insert);
795+
return true;
793796
}
797+
798+
return false;
794799
}
795800

796801
export function sortAndDeduplicate<T>(array: readonly string[]): SortedReadonlyArray<string>;

src/compiler/corePublic.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace ts {
22
// WARNING: The script `configurePrerelease.ts` uses a regexp to parse out these values.
33
// If changing the text in this section, be sure to test `configurePrerelease` too.
4-
export const versionMajorMinor = "4.8";
4+
export const versionMajorMinor = "4.9";
55
// The following is baselined as a literal template type without intervention
66
/** The version of the TypeScript compiler release */
77
// eslint-disable-next-line @typescript-eslint/no-inferrable-types

src/compiler/transformers/declarations.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1217,14 +1217,18 @@ namespace ts {
12171217

12181218
const previousNeedsDeclare = needsDeclare;
12191219
switch (input.kind) {
1220-
case SyntaxKind.TypeAliasDeclaration: // Type aliases get `declare`d if need be (for legacy support), but that's all
1221-
return cleanup(factory.updateTypeAliasDeclaration(
1220+
case SyntaxKind.TypeAliasDeclaration: {
1221+
needsDeclare = false;
1222+
const clean = cleanup(factory.updateTypeAliasDeclaration(
12221223
input,
12231224
ensureModifiers(input),
12241225
input.name,
12251226
visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration),
12261227
visitNode(input.type, visitDeclarationSubtree, isTypeNode)
12271228
));
1229+
needsDeclare = previousNeedsDeclare;
1230+
return clean;
1231+
}
12281232
case SyntaxKind.InterfaceDeclaration: {
12291233
return cleanup(factory.updateInterfaceDeclaration(
12301234
input,

src/compiler/transformers/module/system.ts

+14
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,20 @@ namespace ts {
466466
factory.createAssignment(importVariableName, parameterName)
467467
)
468468
);
469+
if (hasSyntacticModifier(entry, ModifierFlags.Export)) {
470+
statements.push(
471+
factory.createExpressionStatement(
472+
factory.createCallExpression(
473+
exportFunction,
474+
/*typeArguments*/ undefined,
475+
[
476+
factory.createStringLiteral(idText(importVariableName)),
477+
parameterName,
478+
]
479+
)
480+
)
481+
);
482+
}
469483
break;
470484

471485
case SyntaxKind.ExportDeclaration:

0 commit comments

Comments
 (0)