Skip to content

Commit e67ba68

Browse files
committed
Merge remote-tracking branch 'upstream/master'
* upstream/master: (36 commits) Update baselines (microsoft#39000) Make isEntityNameVisible duplicate the node builder logic to always consider type parameters as visible if they are the resolution result (microsoft#38921) Schedule failed lookup updates (microsoft#38560) Remove non null assertion on oldSourceFile.resolvedModules (microsoft#38984) use blocklist instead of blacklist (microsoft#38988) LEGO: check in for master to temporary branch. Deprecate reloadFs so the tests are more clear in what they are achieving and its easier to track changed behaviour (microsoft#38954) LEGO: check in for master to temporary branch. LEGO: check in for master to temporary branch. Make `hasCorrectArity` handle tuples properly fix error when use spread arguments twice fix(38081): allow transforming object binding to named imports Accept baseline fix names Fix type and simplify code accept new baseline fix rebase conflict add missing semi Add more check fix mission baseline ...
2 parents a303bf0 + 895b3c3 commit e67ba68

File tree

175 files changed

+7669
-1063
lines changed

Some content is hidden

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

175 files changed

+7669
-1063
lines changed

src/compiler/binder.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,9 @@ namespace ts {
923923
function isNarrowingBinaryExpression(expr: BinaryExpression) {
924924
switch (expr.operatorToken.kind) {
925925
case SyntaxKind.EqualsToken:
926+
case SyntaxKind.BarBarEqualsToken:
927+
case SyntaxKind.AmpersandAmpersandEqualsToken:
928+
case SyntaxKind.QuestionQuestionEqualsToken:
926929
return containsNarrowableReference(expr.left);
927930
case SyntaxKind.EqualsEqualsToken:
928931
case SyntaxKind.ExclamationEqualsToken:
@@ -1059,12 +1062,18 @@ namespace ts {
10591062
}
10601063
}
10611064

1065+
function isLogicalAssignmentExpression(node: Node) {
1066+
node = skipParentheses(node);
1067+
return isBinaryExpression(node) && isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind);
1068+
}
1069+
10621070
function isTopLevelLogicalExpression(node: Node): boolean {
10631071
while (isParenthesizedExpression(node.parent) ||
10641072
isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.ExclamationToken) {
10651073
node = node.parent;
10661074
}
10671075
return !isStatementCondition(node) &&
1076+
!isLogicalAssignmentExpression(node.parent) &&
10681077
!isLogicalExpression(node.parent) &&
10691078
!(isOptionalChain(node.parent) && node.parent.expression === node);
10701079
}
@@ -1081,7 +1090,7 @@ namespace ts {
10811090

10821091
function bindCondition(node: Expression | undefined, trueTarget: FlowLabel, falseTarget: FlowLabel) {
10831092
doWithConditionalBranches(bind, node, trueTarget, falseTarget);
1084-
if (!node || !isLogicalExpression(node) && !(isOptionalChain(node) && isOutermostOptionalChain(node))) {
1093+
if (!node || !isLogicalAssignmentExpression(node) && !isLogicalExpression(node) && !(isOptionalChain(node) && isOutermostOptionalChain(node))) {
10851094
addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node));
10861095
addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node));
10871096
}
@@ -1422,17 +1431,27 @@ namespace ts {
14221431
}
14231432
}
14241433

1425-
function bindLogicalExpression(node: BinaryExpression, trueTarget: FlowLabel, falseTarget: FlowLabel) {
1434+
function bindLogicalLikeExpression(node: BinaryExpression, trueTarget: FlowLabel, falseTarget: FlowLabel) {
14261435
const preRightLabel = createBranchLabel();
1427-
if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
1436+
if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || node.operatorToken.kind === SyntaxKind.AmpersandAmpersandEqualsToken) {
14281437
bindCondition(node.left, preRightLabel, falseTarget);
14291438
}
14301439
else {
14311440
bindCondition(node.left, trueTarget, preRightLabel);
14321441
}
14331442
currentFlow = finishFlowLabel(preRightLabel);
14341443
bind(node.operatorToken);
1435-
bindCondition(node.right, trueTarget, falseTarget);
1444+
1445+
if (isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind)) {
1446+
doWithConditionalBranches(bind, node.right, trueTarget, falseTarget);
1447+
bindAssignmentTargetFlow(node.left);
1448+
1449+
addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node));
1450+
addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node));
1451+
}
1452+
else {
1453+
bindCondition(node.right, trueTarget, falseTarget);
1454+
}
14361455
}
14371456

14381457
function bindPrefixUnaryExpressionFlow(node: PrefixUnaryExpression) {
@@ -1518,14 +1537,15 @@ namespace ts {
15181537
// TODO: bindLogicalExpression is recursive - if we want to handle deeply nested `&&` expressions
15191538
// we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too
15201539
// For now, though, since the common cases are chained `+`, leaving it recursive is fine
1521-
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
1540+
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken ||
1541+
isLogicalOrCoalescingAssignmentOperator(operator)) {
15221542
if (isTopLevelLogicalExpression(node)) {
15231543
const postExpressionLabel = createBranchLabel();
1524-
bindLogicalExpression(node, postExpressionLabel, postExpressionLabel);
1544+
bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel);
15251545
currentFlow = finishFlowLabel(postExpressionLabel);
15261546
}
15271547
else {
1528-
bindLogicalExpression(node, currentTrueTarget!, currentFalseTarget!);
1548+
bindLogicalLikeExpression(node, currentTrueTarget!, currentFalseTarget!);
15291549
}
15301550
completeNode();
15311551
}
@@ -3639,6 +3659,9 @@ namespace ts {
36393659
if (operatorTokenKind === SyntaxKind.QuestionQuestionToken) {
36403660
transformFlags |= TransformFlags.AssertES2020;
36413661
}
3662+
else if (isLogicalOrCoalescingAssignmentOperator(operatorTokenKind)) {
3663+
transformFlags |= TransformFlags.AssertESNext;
3664+
}
36423665
else if (operatorTokenKind === SyntaxKind.EqualsToken && leftKind === SyntaxKind.ObjectLiteralExpression) {
36433666
// Destructuring object assignments with are ES2015 syntax
36443667
// and possibly ES2018 if they contain rest

src/compiler/checker.ts

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4067,6 +4067,9 @@ namespace ts {
40674067

40684068
const firstIdentifier = getFirstIdentifier(entityName);
40694069
const symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
4070+
if (symbol && symbol.flags & SymbolFlags.TypeParameter && meaning & SymbolFlags.Type) {
4071+
return { accessibility: SymbolAccessibility.Accessible };
4072+
}
40704073

40714074
// Verify if the symbol is accessible
40724075
return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || {
@@ -19864,6 +19867,9 @@ namespace ts {
1986419867
case SyntaxKind.BinaryExpression:
1986519868
switch ((<BinaryExpression>node).operatorToken.kind) {
1986619869
case SyntaxKind.EqualsToken:
19870+
case SyntaxKind.BarBarEqualsToken:
19871+
case SyntaxKind.AmpersandAmpersandEqualsToken:
19872+
case SyntaxKind.QuestionQuestionEqualsToken:
1986719873
return getReferenceCandidate((<BinaryExpression>node).left);
1986819874
case SyntaxKind.CommaToken:
1986919875
return getReferenceCandidate((<BinaryExpression>node).right);
@@ -20838,6 +20844,9 @@ namespace ts {
2083820844
function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
2083920845
switch (expr.operatorToken.kind) {
2084020846
case SyntaxKind.EqualsToken:
20847+
case SyntaxKind.BarBarEqualsToken:
20848+
case SyntaxKind.AmpersandAmpersandEqualsToken:
20849+
case SyntaxKind.QuestionQuestionEqualsToken:
2084120850
return narrowTypeByTruthiness(narrowType(type, expr.right, assumeTrue), expr.left, assumeTrue);
2084220851
case SyntaxKind.EqualsEqualsToken:
2084320852
case SyntaxKind.ExclamationEqualsToken:
@@ -22462,6 +22471,9 @@ namespace ts {
2246222471
const { left, operatorToken, right } = binaryExpression;
2246322472
switch (operatorToken.kind) {
2246422473
case SyntaxKind.EqualsToken:
22474+
case SyntaxKind.AmpersandAmpersandEqualsToken:
22475+
case SyntaxKind.BarBarEqualsToken:
22476+
case SyntaxKind.QuestionQuestionEqualsToken:
2246522477
if (node !== right) {
2246622478
return undefined;
2246722479
}
@@ -25054,22 +25066,40 @@ namespace ts {
2505425066
effectiveParameterCount = args.length === 0 ? effectiveParameterCount : 1; // class may have argumentless ctor functions - still resolve ctor and compare vs props member type
2505525067
effectiveMinimumArguments = Math.min(effectiveMinimumArguments, 1); // sfc may specify context argument - handled by framework and not typechecked
2505625068
}
25069+
else if (!node.arguments) {
25070+
// This only happens when we have something of the form: 'new C'
25071+
Debug.assert(node.kind === SyntaxKind.NewExpression);
25072+
return getMinArgumentCount(signature) === 0;
25073+
}
2505725074
else {
25058-
if (!node.arguments) {
25059-
// This only happens when we have something of the form: 'new C'
25060-
Debug.assert(node.kind === SyntaxKind.NewExpression);
25061-
return getMinArgumentCount(signature) === 0;
25062-
}
25063-
2506425075
argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
2506525076

2506625077
// If we are missing the close parenthesis, the call is incomplete.
2506725078
callIsIncomplete = node.arguments.end === node.end;
2506825079

25069-
// If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range.
25070-
const spreadArgIndex = getSpreadArgumentIndex(args);
25071-
if (spreadArgIndex >= 0) {
25072-
return spreadArgIndex >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || spreadArgIndex < getParameterCount(signature));
25080+
// If one or more spread arguments are present, check that they correspond to a rest parameter or at least that they are in the valid range.
25081+
const firstSpreadArgIndex = getSpreadArgumentIndex(args);
25082+
if (firstSpreadArgIndex >= 0) {
25083+
if (firstSpreadArgIndex === args.length - 1) {
25084+
// Special case, handles the munged arguments that we receive in case of a spread in the end (breaks the arg.expression below)
25085+
// (see below for code that starts with "const spreadArgument")
25086+
return firstSpreadArgIndex >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || firstSpreadArgIndex < getParameterCount(signature));
25087+
}
25088+
25089+
let totalCount = firstSpreadArgIndex; // count previous arguments
25090+
for (let i = firstSpreadArgIndex; i < args.length; i++) {
25091+
const arg = args[i];
25092+
if (!isSpreadArgument(arg)) {
25093+
totalCount += 1;
25094+
}
25095+
else {
25096+
const argType = flowLoopCount ? checkExpression((<SpreadElement>arg).expression) : checkExpressionCached((<SpreadElement>arg).expression);
25097+
totalCount += isTupleType(argType) ? getTypeArguments(argType).length
25098+
: isArrayType(argType) ? 0
25099+
: 1;
25100+
}
25101+
}
25102+
return totalCount >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || totalCount <= getParameterCount(signature));
2507325103
}
2507425104
}
2507525105

@@ -25547,7 +25577,7 @@ namespace ts {
2554725577
const spreadArgument = <SpreadElement>args[length - 1];
2554825578
const type = flowLoopCount ? checkExpression(spreadArgument.expression) : checkExpressionCached(spreadArgument.expression);
2554925579
if (isTupleType(type)) {
25550-
const typeArguments = getTypeArguments(<TypeReference>type);
25580+
const typeArguments = getTypeArguments(type);
2555125581
const restIndex = type.target.hasRestElement ? typeArguments.length - 1 : -1;
2555225582
const syntheticArgs = map(typeArguments, (t, i) => createSyntheticExpression(spreadArgument, t, /*isSpread*/ i === restIndex, type.target.labeledElementDeclarations?.[i]));
2555325583
return concatenate(args.slice(0, length - 1), syntheticArgs);
@@ -28740,17 +28770,35 @@ namespace ts {
2874028770
case SyntaxKind.InKeyword:
2874128771
return checkInExpression(left, right, leftType, rightType);
2874228772
case SyntaxKind.AmpersandAmpersandToken:
28743-
return getTypeFacts(leftType) & TypeFacts.Truthy ?
28773+
case SyntaxKind.AmpersandAmpersandEqualsToken: {
28774+
const resultType = getTypeFacts(leftType) & TypeFacts.Truthy ?
2874428775
getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) :
2874528776
leftType;
28777+
if (operator === SyntaxKind.AmpersandAmpersandEqualsToken) {
28778+
checkAssignmentOperator(rightType);
28779+
}
28780+
return resultType;
28781+
}
2874628782
case SyntaxKind.BarBarToken:
28747-
return getTypeFacts(leftType) & TypeFacts.Falsy ?
28783+
case SyntaxKind.BarBarEqualsToken: {
28784+
const resultType = getTypeFacts(leftType) & TypeFacts.Falsy ?
2874828785
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) :
2874928786
leftType;
28787+
if (operator === SyntaxKind.BarBarEqualsToken) {
28788+
checkAssignmentOperator(rightType);
28789+
}
28790+
return resultType;
28791+
}
2875028792
case SyntaxKind.QuestionQuestionToken:
28751-
return getTypeFacts(leftType) & TypeFacts.EQUndefinedOrNull ?
28793+
case SyntaxKind.QuestionQuestionEqualsToken: {
28794+
const resultType = getTypeFacts(leftType) & TypeFacts.EQUndefinedOrNull ?
2875228795
getUnionType([getNonNullableType(leftType), rightType], UnionReduction.Subtype) :
2875328796
leftType;
28797+
if (operator === SyntaxKind.QuestionQuestionEqualsToken) {
28798+
checkAssignmentOperator(rightType);
28799+
}
28800+
return resultType;
28801+
}
2875428802
case SyntaxKind.EqualsToken:
2875528803
const declKind = isBinaryExpression(left.parent) ? getAssignmentDeclarationKind(left.parent) : AssignmentDeclarationKind.None;
2875628804
checkAssignmentDeclaration(declKind, rightType);

src/compiler/program.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,11 @@ namespace ts {
554554
getSourceVersion: (path: Path, fileName: string) => string | undefined,
555555
fileExists: (fileName: string) => boolean,
556556
hasInvalidatedResolution: HasInvalidatedResolution,
557-
hasChangedAutomaticTypeDirectiveNames: boolean,
557+
hasChangedAutomaticTypeDirectiveNames: HasChangedAutomaticTypeDirectiveNames | undefined,
558558
projectReferences: readonly ProjectReference[] | undefined
559559
): boolean {
560560
// If we haven't created a program yet or have changed automatic type directives, then it is not up-to-date
561-
if (!program || hasChangedAutomaticTypeDirectiveNames) {
561+
if (!program || hasChangedAutomaticTypeDirectiveNames?.()) {
562562
return false;
563563
}
564564

@@ -1110,7 +1110,7 @@ namespace ts {
11101110
const moduleName = moduleNames[i];
11111111
// If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
11121112
if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) {
1113-
const oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules!.get(moduleName);
1113+
const oldResolvedModule = getResolvedModule(oldSourceFile, moduleName);
11141114
if (oldResolvedModule) {
11151115
if (isTraceEnabled(options, host)) {
11161116
trace(host, Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile);
@@ -1424,7 +1424,7 @@ namespace ts {
14241424
return oldProgram.structureIsReused;
14251425
}
14261426

1427-
if (host.hasChangedAutomaticTypeDirectiveNames) {
1427+
if (host.hasChangedAutomaticTypeDirectiveNames?.()) {
14281428
return oldProgram.structureIsReused = StructureIsReused.SafeModules;
14291429
}
14301430

0 commit comments

Comments
 (0)