diff --git a/lib/tsc.js b/lib/tsc.js index d079b6799de97e43ef5047865f32c415ce050440..ef77c0fa69f704b5d0d629bdfba87f555a0d1e73 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -39913,6 +39913,7 @@ var ts; var preSwitchCaseFlow; var activeLabelList; var hasExplicitReturn; + var hasFlowEffects; var emitFlags; var inStrictMode; var inAssignmentPattern = false; @@ -39964,6 +39965,7 @@ var ts; currentExceptionTarget = undefined; activeLabelList = undefined; hasExplicitReturn = false; + hasFlowEffects = false; inAssignmentPattern = false; emitFlags = 0; } @@ -40411,8 +40413,8 @@ var ts; function isNarrowingExpression(expr) { switch (expr.kind) { case 79: - case 80: case 109: + return true; case 211: case 212: return containsNarrowableReference(expr); @@ -40431,11 +40433,24 @@ var ts; return false; } function isNarrowableReference(expr) { - return ts.isDottedName(expr) - || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || ts.isBinaryExpression(expr) && expr.operatorToken.kind === 27 && isNarrowableReference(expr.right) - || ts.isElementAccessExpression(expr) && (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || ts.isAssignmentExpression(expr) && isNarrowableReference(expr.left); + switch (expr.kind) { + case 79: + case 109: + case 107: + case 237: + return true; + case 211: + case 217: + case 236: + return isNarrowableReference(expr.expression); + case 212: + return (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && + isNarrowableReference(expr.expression); + case 227: + return expr.operatorToken.kind === 27 && isNarrowableReference(expr.right) || + ts.isAssignmentOperator(expr.operatorToken.kind) && ts.isLeftHandSideExpression(expr.left); + } + return false; } function containsNarrowableReference(expr) { return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); @@ -40536,6 +40551,7 @@ var ts; } function createFlowMutation(flags, antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node }); if (currentExceptionTarget) { addAntecedent(currentExceptionTarget, result); @@ -40544,6 +40560,7 @@ var ts; } function createFlowCall(antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; return initFlowNode({ flags: 512, antecedent: antecedent, node: node }); } function finishFlowLabel(flow) { @@ -40709,6 +40726,7 @@ var ts; } } currentFlow = unreachableFlow; + hasFlowEffects = true; } function findActiveLabel(name) { for (var label = activeLabelList; label; label = label.next) { @@ -40723,6 +40741,7 @@ var ts; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; + hasFlowEffects = true; } } function bindBreakOrContinueStatement(node) { @@ -40986,8 +41005,12 @@ var ts; ts.isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindLogicalLikeExpression(node, currentTrueTarget, currentFalseTarget); @@ -41060,6 +41083,9 @@ var ts; var trueLabel = createBranchLabel(); var falseLabel = createBranchLabel(); var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); @@ -41070,6 +41096,8 @@ var ts; bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } function bindInitializedVariableFlow(node) { var name = !ts.isOmittedExpression(node) ? node.name : undefined; @@ -41173,8 +41201,11 @@ var ts; function bindOptionalChainFlow(node) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; bindOptionalChain(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindOptionalChain(node, currentTrueTarget, currentFalseTarget); @@ -42873,6 +42904,7 @@ var ts; var apparentArgumentCount; var constEnumRelate = new ts.Map(); var performanceFileName; + var qualifiedNameCache = new ts.Map(); var checker = { getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, @@ -43204,6 +43236,7 @@ var ts; getConstEnumRelate: function () { return constEnumRelate; }, clearConstEnumRelate: function () { constEnumRelate && constEnumRelate.clear(); }, deleteConstEnumRelate: function (path) { constEnumRelate && constEnumRelate.delete(path); }, + clearQualifiedNameCache: function () { qualifiedNameCache && qualifiedNameCache.clear(); }, }; function runWithInferenceBlockedFromSourceNode(node, fn) { var containingCall = ts.findAncestor(node, ts.isCallLikeExpression); @@ -45371,7 +45404,21 @@ var ts; } } function getFullyQualifiedName(symbol, containingLocation) { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, undefined, 32 | 4); + if (containingLocation === undefined) { + var cachedQualifiedName = qualifiedNameCache.get(symbol); + if (cachedQualifiedName) { + return cachedQualifiedName; + } + } + var qualifiedName = getFullyQualifiedNameNoCache(symbol, containingLocation); + if (isTypeCheckerForLinter && containingLocation === undefined) { + qualifiedNameCache.set(symbol, qualifiedName); + } + return qualifiedName; + } + function getFullyQualifiedNameNoCache(symbol, containingLocation) { + return symbol.parent ? getFullyQualifiedNameNoCache(symbol.parent, containingLocation) + "." + symbolToString(symbol) : + symbolToString(symbol, containingLocation, undefined, 32 | 4); } function getContainingQualifiedNameNode(node) { while (ts.isQualifiedName(node.parent)) { @@ -46566,7 +46613,9 @@ var ts; return writer ? symbolToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(symbolToStringWorker); function symbolToStringWorker(writer) { var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); - var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 ? ts.createPrinter({ removeComments: true, neverAsciiEscape: true }) : ts.createPrinter({ removeComments: true }); + var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 + ? ts.createPrinterWithRemoveCommentsNeverAsciiEscape() + : ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4, entity, sourceFile, writer); return writer; @@ -46584,7 +46633,7 @@ var ts; sigOutput = kind === 1 ? 180 : 179; } var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 | 512); - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4, sig, sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); return writer; @@ -46597,8 +46646,7 @@ var ts; var typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 | (noTruncation ? 1 : 0), writer); if (typeNode === undefined) return ts.Debug.fail("should always get typenode"); - var options = { removeComments: type !== unresolvedType }; - var printer = ts.createPrinter(options); + var printer = type !== unresolvedType ? ts.createPrinterWithRemoveComments() : ts.createPrinterWithDefaults(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4, typeNode, sourceFile, writer); var result = writer.getText(); @@ -49283,7 +49331,7 @@ var ts; return writer ? typePredicateToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(typePredicateToStringWorker); function typePredicateToStringWorker(writer) { var predicate = ts.factory.createTypePredicateNode(typePredicate.kind === 2 || typePredicate.kind === 3 ? ts.factory.createToken(130) : undefined, typePredicate.kind === 1 || typePredicate.kind === 3 ? ts.factory.createIdentifier(typePredicate.parameterName) : ts.factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 | 512)); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4, predicate, sourceFile, writer); return writer; @@ -54665,7 +54713,7 @@ var ts; origin = createOriginUnionOrIntersectionType(1048576, reducedTypes); } } - var objectFlags = (includes & 36323363 ? 0 : 32768) | + var objectFlags = (includes & 36323331 ? 0 : 32768) | (includes & 2097152 ? 16777216 : 0); return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments, origin); } @@ -54798,7 +54846,7 @@ var ts; var u = unionTypes_1[_i]; if (!containsType(u.types, type)) { var primitive = type.flags & 128 ? stringType : - type.flags & 256 ? numberType : + type.flags & (32 | 256) ? numberType : type.flags & 2048 ? bigintType : type.flags & 8192 ? esSymbolType : undefined; @@ -54830,9 +54878,6 @@ var ts; } return false; } - function eachIsUnionContaining(types, flag) { - return ts.every(types, function (t) { return !!(t.flags & 1048576) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); }); - } function removeFromEach(types, flag) { for (var i = 0; i < types.length; i++) { types[i] = filterType(types[i], function (t) { return !(t.flags & flag); }); @@ -54932,12 +54977,12 @@ var ts; if (intersectUnionsOfPrimitiveTypes(typeSet)) { result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 32768)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 && t.types[0].flags & 32768); })) { var undefinedOrMissingType = exactOptionalPropertyTypes && ts.some(typeSet, function (t) { return containsType(t.types, missingType); }) ? missingType : undefinedType; removeFromEach(typeSet, 32768); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], 1, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 65536)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 && (t.types[0].flags & 65536 || t.types[1].flags & 65536)); })) { removeFromEach(typeSet, 65536); result = getUnionType([getIntersectionType(typeSet), nullType], 1, aliasSymbol, aliasTypeArguments); } @@ -58279,6 +58324,15 @@ var ts; if (containsType(targetTypes, source)) { return -1; } + if (ts.getObjectFlags(target) & 32768 && !(source.flags & 1024) && (source.flags & (128 | 512 | 2048) || + (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & 256)) { + var alternateForm = source === source.regularType ? source.freshType : source.regularType; + var primitive = source.flags & 128 ? stringType : + source.flags & 256 ? numberType : + source.flags & 2048 ? bigintType : + undefined; + return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? -1 : 0; + } var match = getMatchingUnionConstituentForType(target, source); if (match) { var related = isRelatedTo(source, match, 2, false); @@ -97119,6 +97173,10 @@ var ts; return outputFiles; } ts.emitUsingBuildInfo = emitUsingBuildInfo; + ts.createPrinterWithDefaults = ts.memoize(function () { return createPrinter({}); }); + ts.createPrinterWithRemoveComments = ts.memoize(function () { return createPrinter({ removeComments: true }); }); + ts.createPrinterWithRemoveCommentsNeverAsciiEscape = ts.memoize(function () { return createPrinter({ removeComments: true, neverAsciiEscape: true }); }); + ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon = ts.memoize(function () { return createPrinter({ removeComments: true, omitTrailingSemicolon: true }); }); function createPrinter(printerOptions, handlers) { if (printerOptions === void 0) { printerOptions = {}; } if (handlers === void 0) { handlers = {}; } diff --git a/lib/tsserver.js b/lib/tsserver.js index b1f67ca85b18539d35969fb0b574ccf368c16901..da6bd23e4f397c20a77a15a8d5f1dbe86f9b62dc 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -5430,7 +5430,7 @@ var ts; /* @internal */ TypeFlags[TypeFlags["IncludesInstantiable"] = 33554432] = "IncludesInstantiable"; /* @internal */ - TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323363] = "NotPrimitiveUnion"; + TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323331] = "NotPrimitiveUnion"; })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {})); // Types included in TypeFlags.ObjectFlagsType have an objectFlags property. Some ObjectFlags // are specific to certain types and reuse the same bit position. Those ObjectFlags require a check @@ -39323,7 +39323,7 @@ var ts; return withJSDoc(finishNode(node, pos), hasJSDoc); } function isSetLazy(identifier) { - // 1. import lazy { export } from "mod"; + // 1. import lazy { export } from "mod"; // 2. import lazy defaultExport from "mod"; // 3. import lazy defaultExport, { export, /* ... */ } from "mod"; return (identifier === null || identifier === void 0 ? void 0 : identifier.escapedText) === 'lazy' && @@ -48427,6 +48427,7 @@ var ts; var preSwitchCaseFlow; var activeLabelList; var hasExplicitReturn; + var hasFlowEffects; // state used for emit helpers var emitFlags; // If this file is an external module, then it is automatically in strict-mode according to @@ -48490,6 +48491,7 @@ var ts; currentExceptionTarget = undefined; activeLabelList = undefined; hasExplicitReturn = false; + hasFlowEffects = false; inAssignmentPattern = false; emitFlags = 0 /* NodeFlags.None */; } @@ -49050,8 +49052,8 @@ var ts; function isNarrowingExpression(expr) { switch (expr.kind) { case 79 /* SyntaxKind.Identifier */: - case 80 /* SyntaxKind.PrivateIdentifier */: case 109 /* SyntaxKind.ThisKeyword */: + return true; case 211 /* SyntaxKind.PropertyAccessExpression */: case 212 /* SyntaxKind.ElementAccessExpression */: return containsNarrowableReference(expr); @@ -49070,11 +49072,24 @@ var ts; return false; } function isNarrowableReference(expr) { - return ts.isDottedName(expr) - || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || ts.isBinaryExpression(expr) && expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) - || ts.isElementAccessExpression(expr) && (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || ts.isAssignmentExpression(expr) && isNarrowableReference(expr.left); + switch (expr.kind) { + case 79 /* SyntaxKind.Identifier */: + case 109 /* SyntaxKind.ThisKeyword */: + case 107 /* SyntaxKind.SuperKeyword */: + case 237 /* SyntaxKind.MetaProperty */: + return true; + case 211 /* SyntaxKind.PropertyAccessExpression */: + case 217 /* SyntaxKind.ParenthesizedExpression */: + case 236 /* SyntaxKind.NonNullExpression */: + return isNarrowableReference(expr.expression); + case 212 /* SyntaxKind.ElementAccessExpression */: + return (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && + isNarrowableReference(expr.expression); + case 227 /* SyntaxKind.BinaryExpression */: + return expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) || + ts.isAssignmentOperator(expr.operatorToken.kind) && ts.isLeftHandSideExpression(expr.left); + } + return false; } function containsNarrowableReference(expr) { return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); @@ -49176,6 +49191,7 @@ var ts; } function createFlowMutation(flags, antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node }); if (currentExceptionTarget) { addAntecedent(currentExceptionTarget, result); @@ -49184,6 +49200,7 @@ var ts; } function createFlowCall(antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; return initFlowNode({ flags: 512 /* FlowFlags.Call */, antecedent: antecedent, node: node }); } function finishFlowLabel(flow) { @@ -49349,6 +49366,7 @@ var ts; } } currentFlow = unreachableFlow; + hasFlowEffects = true; } function findActiveLabel(name) { for (var label = activeLabelList; label; label = label.next) { @@ -49363,6 +49381,7 @@ var ts; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; + hasFlowEffects = true; } } function bindBreakOrContinueStatement(node) { @@ -49668,8 +49687,12 @@ var ts; ts.isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindLogicalLikeExpression(node, currentTrueTarget, currentFalseTarget); @@ -49742,6 +49765,9 @@ var ts; var trueLabel = createBranchLabel(); var falseLabel = createBranchLabel(); var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); @@ -49752,6 +49778,8 @@ var ts; bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } function bindInitializedVariableFlow(node) { var name = !ts.isOmittedExpression(node) ? node.name : undefined; @@ -49873,8 +49901,11 @@ var ts; function bindOptionalChainFlow(node) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; bindOptionalChain(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindOptionalChain(node, currentTrueTarget, currentFalseTarget); @@ -52042,6 +52073,8 @@ var ts; var apparentArgumentCount; var constEnumRelate = new ts.Map(); var performanceFileName; + // Used only for linter, in non-strict typeChecker, it is always empty. + var qualifiedNameCache = new ts.Map(); // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. // for most of these, we perform the guard only on `checker` to avoid any possible @@ -52385,6 +52418,7 @@ var ts; getConstEnumRelate: function () { return constEnumRelate; }, clearConstEnumRelate: function () { constEnumRelate && constEnumRelate.clear(); }, deleteConstEnumRelate: function (path) { constEnumRelate && constEnumRelate.delete(path); }, + clearQualifiedNameCache: function () { qualifiedNameCache && qualifiedNameCache.clear(); }, }; function runWithInferenceBlockedFromSourceNode(node, fn) { var containingCall = ts.findAncestor(node, ts.isCallLikeExpression); @@ -54895,7 +54929,21 @@ var ts; } } function getFullyQualifiedName(symbol, containingLocation) { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); + if (containingLocation === undefined) { + var cachedQualifiedName = qualifiedNameCache.get(symbol); + if (cachedQualifiedName) { + return cachedQualifiedName; + } + } + var qualifiedName = getFullyQualifiedNameNoCache(symbol, containingLocation); + if (isTypeCheckerForLinter && containingLocation === undefined) { + qualifiedNameCache.set(symbol, qualifiedName); + } + return qualifiedName; + } + function getFullyQualifiedNameNoCache(symbol, containingLocation) { + return symbol.parent ? getFullyQualifiedNameNoCache(symbol.parent, containingLocation) + "." + symbolToString(symbol) : + symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); } function getContainingQualifiedNameNode(node) { while (ts.isQualifiedName(node.parent)) { @@ -56261,7 +56309,9 @@ var ts; function symbolToStringWorker(writer) { var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217 // add neverAsciiEscape for GH#39027 - var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ ? ts.createPrinter({ removeComments: true, neverAsciiEscape: true }) : ts.createPrinter({ removeComments: true }); + var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ + ? ts.createPrinterWithRemoveCommentsNeverAsciiEscape() + : ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, entity, /*sourceFile*/ sourceFile, writer); return writer; @@ -56279,7 +56329,7 @@ var ts; sigOutput = kind === 1 /* SignatureKind.Construct */ ? 180 /* SyntaxKind.ConstructSignature */ : 179 /* SyntaxKind.CallSignature */; } var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */); - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 return writer; @@ -56294,8 +56344,7 @@ var ts; return ts.Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. - var options = { removeComments: type !== unresolvedType }; - var printer = ts.createPrinter(options); + var printer = type !== unresolvedType ? ts.createPrinterWithRemoveComments() : ts.createPrinterWithDefaults(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); @@ -59371,7 +59420,7 @@ var ts; function typePredicateToStringWorker(writer) { var predicate = ts.factory.createTypePredicateNode(typePredicate.kind === 2 /* TypePredicateKind.AssertsThis */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createToken(130 /* SyntaxKind.AssertsKeyword */) : undefined, typePredicate.kind === 1 /* TypePredicateKind.Identifier */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createIdentifier(typePredicate.parameterName) : ts.factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */) // TODO: GH#18217 ); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, predicate, /*sourceFile*/ sourceFile, writer); return writer; @@ -65504,7 +65553,7 @@ var ts; origin = createOriginUnionOrIntersectionType(1048576 /* TypeFlags.Union */, reducedTypes); } } - var objectFlags = (includes & 36323363 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | + var objectFlags = (includes & 36323331 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | (includes & 2097152 /* TypeFlags.Intersection */ ? 16777216 /* ObjectFlags.ContainsIntersections */ : 0); return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments, origin); } @@ -65647,7 +65696,7 @@ var ts; var u = unionTypes_1[_i]; if (!containsType(u.types, type)) { var primitive = type.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : - type.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + type.flags & (32 /* TypeFlags.Enum */ | 256 /* TypeFlags.NumberLiteral */) ? numberType : type.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : type.flags & 8192 /* TypeFlags.UniqueESSymbol */ ? esSymbolType : undefined; @@ -65683,9 +65732,6 @@ var ts; } return false; } - function eachIsUnionContaining(types, flag) { - return ts.every(types, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); }); - } function removeFromEach(types, flag) { for (var i = 0; i < types.length; i++) { types[i] = filterType(types[i], function (t) { return !(t.flags & flag); }); @@ -65817,12 +65863,12 @@ var ts; // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 32768 /* TypeFlags.Undefined */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && t.types[0].flags & 32768 /* TypeFlags.Undefined */); })) { var undefinedOrMissingType = exactOptionalPropertyTypes && ts.some(typeSet, function (t) { return containsType(t.types, missingType); }) ? missingType : undefinedType; removeFromEach(typeSet, 32768 /* TypeFlags.Undefined */); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 65536 /* TypeFlags.Null */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && (t.types[0].flags & 65536 /* TypeFlags.Null */ || t.types[1].flags & 65536 /* TypeFlags.Null */)); })) { removeFromEach(typeSet, 65536 /* TypeFlags.Null */); result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } @@ -69575,6 +69621,20 @@ var ts; if (containsType(targetTypes, source)) { return -1 /* Ternary.True */; } + if (ts.getObjectFlags(target) & 32768 /* ObjectFlags.PrimitiveUnion */ && !(source.flags & 1024 /* TypeFlags.EnumLiteral */) && (source.flags & (128 /* TypeFlags.StringLiteral */ | 512 /* TypeFlags.BooleanLiteral */ | 2048 /* TypeFlags.BigIntLiteral */) || + (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & 256 /* TypeFlags.NumberLiteral */)) { + // When relating a literal type to a union of primitive types, we know the relation is false unless + // the union contains the base primitive type or the literal type in one of its fresh/regular forms. + // We exclude numeric literals for non-subtype relations because numeric literals are assignable to + // numeric enum literals with the same value. Similarly, we exclude enum literal types because + // identically named enum types are related (see isEmumTypeRelatedTo). + var alternateForm = source === source.regularType ? source.freshType : source.regularType; + var primitive = source.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : + source.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + source.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : + undefined; + return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? -1 /* Ternary.True */ : 0 /* Ternary.False */; + } var match = getMatchingUnionConstituentForType(target, source); if (match) { var related = isRelatedTo(source, match, 2 /* RecursionFlags.Target */, /*reportErrors*/ false); @@ -117545,6 +117605,14 @@ var ts; PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps"; PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit"; })(PipelinePhase || (PipelinePhase = {})); + /** @internal */ + ts.createPrinterWithDefaults = ts.memoize(function () { return createPrinter({}); }); + /** @internal */ + ts.createPrinterWithRemoveComments = ts.memoize(function () { return createPrinter({ removeComments: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsNeverAsciiEscape = ts.memoize(function () { return createPrinter({ removeComments: true, neverAsciiEscape: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon = ts.memoize(function () { return createPrinter({ removeComments: true, omitTrailingSemicolon: true }); }); function createPrinter(printerOptions, handlers) { if (printerOptions === void 0) { printerOptions = {}; } if (handlers === void 0) { handlers = {}; } @@ -136353,7 +136421,7 @@ var ts; function nodeToDisplayParts(node, enclosingDeclaration) { var file = enclosingDeclaration.getSourceFile(); return mapToDisplayParts(function (writer) { - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); printer.writeNode(4 /* EmitHint.Unspecified */, node, file, writer); }); } @@ -147082,7 +147150,7 @@ var ts; } if (text === undefined) { // get the text from printing the node on a single line without comments... - var printer_1 = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer_1 = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); text = ts.usingSingleLineStringWriter(function (writer) { return printer_1.writeNode(4 /* EmitHint.Unspecified */, node, node.getSourceFile(), writer); }); } return { text: text, pos: declName.getStart(), end: declName.getEnd() }; @@ -152351,7 +152419,7 @@ var ts; } function getTypeHelpItem(symbol, typeParameters, checker, enclosingDeclaration, sourceFile) { var typeSymbolDisplay = ts.symbolToDisplayParts(checker, symbol); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = typeParameters.map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var documentation = symbol.getDocumentationComment(checker); var tags = symbol.getJsDocTags(checker); @@ -152385,7 +152453,7 @@ var ts; } function itemInfoForTypeParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = (typeParameters || ts.emptyArray).map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)] : []; return checker.getExpandedParameters(candidateSignature).map(function (paramList) { @@ -152397,7 +152465,7 @@ var ts; }); } function itemInfoForParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var typeParameterParts = ts.mapToDisplayParts(function (writer) { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { var args = ts.factory.createNodeArray(candidateSignature.typeParameters.map(function (p) { return checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags); })); @@ -152700,8 +152768,7 @@ var ts; } function printTypeInSingleLine(type) { var flags = 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 1048576 /* TypeFormatFlags.AllowUniqueESSymbolType */ | 16384 /* TypeFormatFlags.UseAliasDefinedOutsideCurrentScope */; - var options = { removeComments: true }; - var printer = ts.createPrinter(options); + var printer = ts.createPrinterWithRemoveComments(); return ts.usingSingleLineStringWriter(function (writer) { var typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags, writer); ts.Debug.assertIsDefined(typeNode, "should always get typenode"); @@ -153246,7 +153313,6 @@ var ts; var hasAddedSymbolInfo = false; var isThisExpression = location.kind === 109 /* SyntaxKind.ThisKeyword */ && ts.isInExpressionContext(location) || ts.isThisInTypeQuery(location); var type; - var printer; var documentationFromAlias; var tagsFromAlias; var hasMultipleSignatures = false; @@ -153689,10 +153755,7 @@ var ts; } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags.length === 0 ? undefined : tags }; function getPrinter() { - if (!printer) { - printer = ts.createPrinter({ removeComments: true }); - } - return printer; + return ts.createPrinterWithRemoveComments(); } function prefixNextMeaning() { if (displayParts.length) { @@ -173834,6 +173897,9 @@ var ts; ts.PerformanceDotting.start("isProgramUptoDate"); if (ts.isProgramUptoDate(program, rootFileNames, newSettings, function (_path, fileName) { return host.getScriptVersion(fileName); }, function (fileName) { return compilerHost.fileExists(fileName); }, hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { ts.PerformanceDotting.stop("isProgramUptoDate"); + // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches; + // clear these caches to avoid affecting future compilations. + host.clearFileCache && host.clearFileCache(); return; } ts.PerformanceDotting.stop("isProgramUptoDate"); @@ -173877,6 +173943,7 @@ var ts; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); + host.clearFileCache && host.clearFileCache(); return; function getParsedCommandLine(fileName) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); @@ -193049,6 +193116,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { if (autofixable === void 0) { autofixable = false; } if (!TypeScriptLinter.strictMode && faultsAttrs[faultId].migratable) { @@ -194844,6 +194916,7 @@ var ts; ArkTSLinter_1_0.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_0.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_0.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_0.Utils.clearTypeChecker(); ArkTSLinter_1_0.Utils.clearTrueSymbolAtLocationCache(); @@ -198455,6 +198528,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { var _a, _b; if (autofixable === void 0) { autofixable = false; } @@ -201280,6 +201358,7 @@ var ts; ArkTSLinter_1_1.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_1.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_1.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.InteropTypescriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.Utils.clearTypeChecker(); diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 765702bc62431c1a0b189add7ae40f69c94deee9..a07c00f2a53616b8e2c6e1de8847828bcb2d15b7 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -2543,6 +2543,7 @@ declare namespace ts { getConstEnumRelate?(): ESMap>; clearConstEnumRelate?(): void; deleteConstEnumRelate?(path: string): void; + clearQualifiedNameCache?(): void; } export enum NodeBuilderFlags { None = 0, @@ -6378,6 +6379,7 @@ declare namespace ts { shouldCompletionSortCustom?: boolean; uiProps?: string[]; clearProps?(): void; + clearFileCache?(): void; } type WithMetadata = T & { metadata?: unknown; @@ -13014,6 +13016,7 @@ declare namespace ts { skipArkTSStaticBlocksCheck: boolean; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void>; incrementCounters(node: Node | CommentRange, faultId: number, autofixable?: boolean, autofix?: Autofix[]): void; visitTSNode(node: Node): void; @@ -13632,6 +13635,7 @@ declare namespace ts { private compatibleSdkVersion; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void; name: string; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 99f576ac0f1e4d0263855cb6a891035913771a70..0332d8e54bc9715e4c9168e06f9ebc05196a07f7 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -5429,7 +5429,7 @@ var ts; /* @internal */ TypeFlags[TypeFlags["IncludesInstantiable"] = 33554432] = "IncludesInstantiable"; /* @internal */ - TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323363] = "NotPrimitiveUnion"; + TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323331] = "NotPrimitiveUnion"; })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {})); // Types included in TypeFlags.ObjectFlagsType have an objectFlags property. Some ObjectFlags // are specific to certain types and reuse the same bit position. Those ObjectFlags require a check @@ -39322,7 +39322,7 @@ var ts; return withJSDoc(finishNode(node, pos), hasJSDoc); } function isSetLazy(identifier) { - // 1. import lazy { export } from "mod"; + // 1. import lazy { export } from "mod"; // 2. import lazy defaultExport from "mod"; // 3. import lazy defaultExport, { export, /* ... */ } from "mod"; return (identifier === null || identifier === void 0 ? void 0 : identifier.escapedText) === 'lazy' && @@ -48426,6 +48426,7 @@ var ts; var preSwitchCaseFlow; var activeLabelList; var hasExplicitReturn; + var hasFlowEffects; // state used for emit helpers var emitFlags; // If this file is an external module, then it is automatically in strict-mode according to @@ -48489,6 +48490,7 @@ var ts; currentExceptionTarget = undefined; activeLabelList = undefined; hasExplicitReturn = false; + hasFlowEffects = false; inAssignmentPattern = false; emitFlags = 0 /* NodeFlags.None */; } @@ -49049,8 +49051,8 @@ var ts; function isNarrowingExpression(expr) { switch (expr.kind) { case 79 /* SyntaxKind.Identifier */: - case 80 /* SyntaxKind.PrivateIdentifier */: case 109 /* SyntaxKind.ThisKeyword */: + return true; case 211 /* SyntaxKind.PropertyAccessExpression */: case 212 /* SyntaxKind.ElementAccessExpression */: return containsNarrowableReference(expr); @@ -49069,11 +49071,24 @@ var ts; return false; } function isNarrowableReference(expr) { - return ts.isDottedName(expr) - || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || ts.isBinaryExpression(expr) && expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) - || ts.isElementAccessExpression(expr) && (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || ts.isAssignmentExpression(expr) && isNarrowableReference(expr.left); + switch (expr.kind) { + case 79 /* SyntaxKind.Identifier */: + case 109 /* SyntaxKind.ThisKeyword */: + case 107 /* SyntaxKind.SuperKeyword */: + case 237 /* SyntaxKind.MetaProperty */: + return true; + case 211 /* SyntaxKind.PropertyAccessExpression */: + case 217 /* SyntaxKind.ParenthesizedExpression */: + case 236 /* SyntaxKind.NonNullExpression */: + return isNarrowableReference(expr.expression); + case 212 /* SyntaxKind.ElementAccessExpression */: + return (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && + isNarrowableReference(expr.expression); + case 227 /* SyntaxKind.BinaryExpression */: + return expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) || + ts.isAssignmentOperator(expr.operatorToken.kind) && ts.isLeftHandSideExpression(expr.left); + } + return false; } function containsNarrowableReference(expr) { return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); @@ -49175,6 +49190,7 @@ var ts; } function createFlowMutation(flags, antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node }); if (currentExceptionTarget) { addAntecedent(currentExceptionTarget, result); @@ -49183,6 +49199,7 @@ var ts; } function createFlowCall(antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; return initFlowNode({ flags: 512 /* FlowFlags.Call */, antecedent: antecedent, node: node }); } function finishFlowLabel(flow) { @@ -49348,6 +49365,7 @@ var ts; } } currentFlow = unreachableFlow; + hasFlowEffects = true; } function findActiveLabel(name) { for (var label = activeLabelList; label; label = label.next) { @@ -49362,6 +49380,7 @@ var ts; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; + hasFlowEffects = true; } } function bindBreakOrContinueStatement(node) { @@ -49667,8 +49686,12 @@ var ts; ts.isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindLogicalLikeExpression(node, currentTrueTarget, currentFalseTarget); @@ -49741,6 +49764,9 @@ var ts; var trueLabel = createBranchLabel(); var falseLabel = createBranchLabel(); var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); @@ -49751,6 +49777,8 @@ var ts; bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } function bindInitializedVariableFlow(node) { var name = !ts.isOmittedExpression(node) ? node.name : undefined; @@ -49872,8 +49900,11 @@ var ts; function bindOptionalChainFlow(node) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; bindOptionalChain(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindOptionalChain(node, currentTrueTarget, currentFalseTarget); @@ -52041,6 +52072,8 @@ var ts; var apparentArgumentCount; var constEnumRelate = new ts.Map(); var performanceFileName; + // Used only for linter, in non-strict typeChecker, it is always empty. + var qualifiedNameCache = new ts.Map(); // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. // for most of these, we perform the guard only on `checker` to avoid any possible @@ -52384,6 +52417,7 @@ var ts; getConstEnumRelate: function () { return constEnumRelate; }, clearConstEnumRelate: function () { constEnumRelate && constEnumRelate.clear(); }, deleteConstEnumRelate: function (path) { constEnumRelate && constEnumRelate.delete(path); }, + clearQualifiedNameCache: function () { qualifiedNameCache && qualifiedNameCache.clear(); }, }; function runWithInferenceBlockedFromSourceNode(node, fn) { var containingCall = ts.findAncestor(node, ts.isCallLikeExpression); @@ -54894,7 +54928,21 @@ var ts; } } function getFullyQualifiedName(symbol, containingLocation) { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); + if (containingLocation === undefined) { + var cachedQualifiedName = qualifiedNameCache.get(symbol); + if (cachedQualifiedName) { + return cachedQualifiedName; + } + } + var qualifiedName = getFullyQualifiedNameNoCache(symbol, containingLocation); + if (isTypeCheckerForLinter && containingLocation === undefined) { + qualifiedNameCache.set(symbol, qualifiedName); + } + return qualifiedName; + } + function getFullyQualifiedNameNoCache(symbol, containingLocation) { + return symbol.parent ? getFullyQualifiedNameNoCache(symbol.parent, containingLocation) + "." + symbolToString(symbol) : + symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); } function getContainingQualifiedNameNode(node) { while (ts.isQualifiedName(node.parent)) { @@ -56260,7 +56308,9 @@ var ts; function symbolToStringWorker(writer) { var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217 // add neverAsciiEscape for GH#39027 - var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ ? ts.createPrinter({ removeComments: true, neverAsciiEscape: true }) : ts.createPrinter({ removeComments: true }); + var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ + ? ts.createPrinterWithRemoveCommentsNeverAsciiEscape() + : ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, entity, /*sourceFile*/ sourceFile, writer); return writer; @@ -56278,7 +56328,7 @@ var ts; sigOutput = kind === 1 /* SignatureKind.Construct */ ? 180 /* SyntaxKind.ConstructSignature */ : 179 /* SyntaxKind.CallSignature */; } var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */); - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 return writer; @@ -56293,8 +56343,7 @@ var ts; return ts.Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. - var options = { removeComments: type !== unresolvedType }; - var printer = ts.createPrinter(options); + var printer = type !== unresolvedType ? ts.createPrinterWithRemoveComments() : ts.createPrinterWithDefaults(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); @@ -59370,7 +59419,7 @@ var ts; function typePredicateToStringWorker(writer) { var predicate = ts.factory.createTypePredicateNode(typePredicate.kind === 2 /* TypePredicateKind.AssertsThis */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createToken(130 /* SyntaxKind.AssertsKeyword */) : undefined, typePredicate.kind === 1 /* TypePredicateKind.Identifier */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createIdentifier(typePredicate.parameterName) : ts.factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */) // TODO: GH#18217 ); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, predicate, /*sourceFile*/ sourceFile, writer); return writer; @@ -65503,7 +65552,7 @@ var ts; origin = createOriginUnionOrIntersectionType(1048576 /* TypeFlags.Union */, reducedTypes); } } - var objectFlags = (includes & 36323363 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | + var objectFlags = (includes & 36323331 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | (includes & 2097152 /* TypeFlags.Intersection */ ? 16777216 /* ObjectFlags.ContainsIntersections */ : 0); return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments, origin); } @@ -65646,7 +65695,7 @@ var ts; var u = unionTypes_1[_i]; if (!containsType(u.types, type)) { var primitive = type.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : - type.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + type.flags & (32 /* TypeFlags.Enum */ | 256 /* TypeFlags.NumberLiteral */) ? numberType : type.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : type.flags & 8192 /* TypeFlags.UniqueESSymbol */ ? esSymbolType : undefined; @@ -65682,9 +65731,6 @@ var ts; } return false; } - function eachIsUnionContaining(types, flag) { - return ts.every(types, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); }); - } function removeFromEach(types, flag) { for (var i = 0; i < types.length; i++) { types[i] = filterType(types[i], function (t) { return !(t.flags & flag); }); @@ -65816,12 +65862,12 @@ var ts; // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 32768 /* TypeFlags.Undefined */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && t.types[0].flags & 32768 /* TypeFlags.Undefined */); })) { var undefinedOrMissingType = exactOptionalPropertyTypes && ts.some(typeSet, function (t) { return containsType(t.types, missingType); }) ? missingType : undefinedType; removeFromEach(typeSet, 32768 /* TypeFlags.Undefined */); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 65536 /* TypeFlags.Null */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && (t.types[0].flags & 65536 /* TypeFlags.Null */ || t.types[1].flags & 65536 /* TypeFlags.Null */)); })) { removeFromEach(typeSet, 65536 /* TypeFlags.Null */); result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } @@ -69574,6 +69620,20 @@ var ts; if (containsType(targetTypes, source)) { return -1 /* Ternary.True */; } + if (ts.getObjectFlags(target) & 32768 /* ObjectFlags.PrimitiveUnion */ && !(source.flags & 1024 /* TypeFlags.EnumLiteral */) && (source.flags & (128 /* TypeFlags.StringLiteral */ | 512 /* TypeFlags.BooleanLiteral */ | 2048 /* TypeFlags.BigIntLiteral */) || + (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & 256 /* TypeFlags.NumberLiteral */)) { + // When relating a literal type to a union of primitive types, we know the relation is false unless + // the union contains the base primitive type or the literal type in one of its fresh/regular forms. + // We exclude numeric literals for non-subtype relations because numeric literals are assignable to + // numeric enum literals with the same value. Similarly, we exclude enum literal types because + // identically named enum types are related (see isEmumTypeRelatedTo). + var alternateForm = source === source.regularType ? source.freshType : source.regularType; + var primitive = source.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : + source.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + source.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : + undefined; + return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? -1 /* Ternary.True */ : 0 /* Ternary.False */; + } var match = getMatchingUnionConstituentForType(target, source); if (match) { var related = isRelatedTo(source, match, 2 /* RecursionFlags.Target */, /*reportErrors*/ false); @@ -117544,6 +117604,14 @@ var ts; PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps"; PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit"; })(PipelinePhase || (PipelinePhase = {})); + /** @internal */ + ts.createPrinterWithDefaults = ts.memoize(function () { return createPrinter({}); }); + /** @internal */ + ts.createPrinterWithRemoveComments = ts.memoize(function () { return createPrinter({ removeComments: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsNeverAsciiEscape = ts.memoize(function () { return createPrinter({ removeComments: true, neverAsciiEscape: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon = ts.memoize(function () { return createPrinter({ removeComments: true, omitTrailingSemicolon: true }); }); function createPrinter(printerOptions, handlers) { if (printerOptions === void 0) { printerOptions = {}; } if (handlers === void 0) { handlers = {}; } @@ -136772,7 +136840,7 @@ var ts; function nodeToDisplayParts(node, enclosingDeclaration) { var file = enclosingDeclaration.getSourceFile(); return mapToDisplayParts(function (writer) { - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); printer.writeNode(4 /* EmitHint.Unspecified */, node, file, writer); }); } @@ -147501,7 +147569,7 @@ var ts; } if (text === undefined) { // get the text from printing the node on a single line without comments... - var printer_1 = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer_1 = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); text = ts.usingSingleLineStringWriter(function (writer) { return printer_1.writeNode(4 /* EmitHint.Unspecified */, node, node.getSourceFile(), writer); }); } return { text: text, pos: declName.getStart(), end: declName.getEnd() }; @@ -152770,7 +152838,7 @@ var ts; } function getTypeHelpItem(symbol, typeParameters, checker, enclosingDeclaration, sourceFile) { var typeSymbolDisplay = ts.symbolToDisplayParts(checker, symbol); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = typeParameters.map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var documentation = symbol.getDocumentationComment(checker); var tags = symbol.getJsDocTags(checker); @@ -152804,7 +152872,7 @@ var ts; } function itemInfoForTypeParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = (typeParameters || ts.emptyArray).map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)] : []; return checker.getExpandedParameters(candidateSignature).map(function (paramList) { @@ -152816,7 +152884,7 @@ var ts; }); } function itemInfoForParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var typeParameterParts = ts.mapToDisplayParts(function (writer) { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { var args = ts.factory.createNodeArray(candidateSignature.typeParameters.map(function (p) { return checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags); })); @@ -153119,8 +153187,7 @@ var ts; } function printTypeInSingleLine(type) { var flags = 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 1048576 /* TypeFormatFlags.AllowUniqueESSymbolType */ | 16384 /* TypeFormatFlags.UseAliasDefinedOutsideCurrentScope */; - var options = { removeComments: true }; - var printer = ts.createPrinter(options); + var printer = ts.createPrinterWithRemoveComments(); return ts.usingSingleLineStringWriter(function (writer) { var typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags, writer); ts.Debug.assertIsDefined(typeNode, "should always get typenode"); @@ -153665,7 +153732,6 @@ var ts; var hasAddedSymbolInfo = false; var isThisExpression = location.kind === 109 /* SyntaxKind.ThisKeyword */ && ts.isInExpressionContext(location) || ts.isThisInTypeQuery(location); var type; - var printer; var documentationFromAlias; var tagsFromAlias; var hasMultipleSignatures = false; @@ -154108,10 +154174,7 @@ var ts; } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags.length === 0 ? undefined : tags }; function getPrinter() { - if (!printer) { - printer = ts.createPrinter({ removeComments: true }); - } - return printer; + return ts.createPrinterWithRemoveComments(); } function prefixNextMeaning() { if (displayParts.length) { @@ -174253,6 +174316,9 @@ var ts; ts.PerformanceDotting.start("isProgramUptoDate"); if (ts.isProgramUptoDate(program, rootFileNames, newSettings, function (_path, fileName) { return host.getScriptVersion(fileName); }, function (fileName) { return compilerHost.fileExists(fileName); }, hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { ts.PerformanceDotting.stop("isProgramUptoDate"); + // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches; + // clear these caches to avoid affecting future compilations. + host.clearFileCache && host.clearFileCache(); return; } ts.PerformanceDotting.stop("isProgramUptoDate"); @@ -174296,6 +174362,7 @@ var ts; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); + host.clearFileCache && host.clearFileCache(); return; function getParsedCommandLine(fileName) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); @@ -192794,6 +192861,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { if (autofixable === void 0) { autofixable = false; } if (!TypeScriptLinter.strictMode && faultsAttrs[faultId].migratable) { @@ -194589,6 +194661,7 @@ var ts; ArkTSLinter_1_0.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_0.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_0.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_0.Utils.clearTypeChecker(); ArkTSLinter_1_0.Utils.clearTrueSymbolAtLocationCache(); @@ -198200,6 +198273,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { var _a, _b; if (autofixable === void 0) { autofixable = false; } @@ -201025,6 +201103,7 @@ var ts; ArkTSLinter_1_1.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_1.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_1.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.InteropTypescriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.Utils.clearTypeChecker(); diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 174833fb51ac267d2b6fc405ee56498bb5a85c7a..ce41ad5ba41198b49643f2bf0ad9c9e7e9e27403 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -2543,6 +2543,7 @@ declare namespace ts { getConstEnumRelate?(): ESMap>; clearConstEnumRelate?(): void; deleteConstEnumRelate?(path: string): void; + clearQualifiedNameCache?(): void; } export enum NodeBuilderFlags { None = 0, @@ -6378,6 +6379,7 @@ declare namespace ts { shouldCompletionSortCustom?: boolean; uiProps?: string[]; clearProps?(): void; + clearFileCache?(): void; } type WithMetadata = T & { metadata?: unknown; @@ -9068,6 +9070,7 @@ declare namespace ts { skipArkTSStaticBlocksCheck: boolean; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void>; incrementCounters(node: Node | CommentRange, faultId: number, autofixable?: boolean, autofix?: Autofix[]): void; visitTSNode(node: Node): void; @@ -9686,6 +9689,7 @@ declare namespace ts { private compatibleSdkVersion; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void; name: string; diff --git a/lib/typescript.js b/lib/typescript.js index 5630daaf70339a4bd778b5f50317fe4c6d292c21..50407ad4856a523e6f6398a5b9bc4cf33d933f30 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -5420,7 +5420,7 @@ var ts; /* @internal */ TypeFlags[TypeFlags["IncludesInstantiable"] = 33554432] = "IncludesInstantiable"; /* @internal */ - TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323363] = "NotPrimitiveUnion"; + TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323331] = "NotPrimitiveUnion"; })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {})); // Types included in TypeFlags.ObjectFlagsType have an objectFlags property. Some ObjectFlags // are specific to certain types and reuse the same bit position. Those ObjectFlags require a check @@ -39313,7 +39313,7 @@ var ts; return withJSDoc(finishNode(node, pos), hasJSDoc); } function isSetLazy(identifier) { - // 1. import lazy { export } from "mod"; + // 1. import lazy { export } from "mod"; // 2. import lazy defaultExport from "mod"; // 3. import lazy defaultExport, { export, /* ... */ } from "mod"; return (identifier === null || identifier === void 0 ? void 0 : identifier.escapedText) === 'lazy' && @@ -48417,6 +48417,7 @@ var ts; var preSwitchCaseFlow; var activeLabelList; var hasExplicitReturn; + var hasFlowEffects; // state used for emit helpers var emitFlags; // If this file is an external module, then it is automatically in strict-mode according to @@ -48480,6 +48481,7 @@ var ts; currentExceptionTarget = undefined; activeLabelList = undefined; hasExplicitReturn = false; + hasFlowEffects = false; inAssignmentPattern = false; emitFlags = 0 /* NodeFlags.None */; } @@ -49040,8 +49042,8 @@ var ts; function isNarrowingExpression(expr) { switch (expr.kind) { case 79 /* SyntaxKind.Identifier */: - case 80 /* SyntaxKind.PrivateIdentifier */: case 109 /* SyntaxKind.ThisKeyword */: + return true; case 211 /* SyntaxKind.PropertyAccessExpression */: case 212 /* SyntaxKind.ElementAccessExpression */: return containsNarrowableReference(expr); @@ -49060,11 +49062,24 @@ var ts; return false; } function isNarrowableReference(expr) { - return ts.isDottedName(expr) - || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || ts.isBinaryExpression(expr) && expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) - || ts.isElementAccessExpression(expr) && (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || ts.isAssignmentExpression(expr) && isNarrowableReference(expr.left); + switch (expr.kind) { + case 79 /* SyntaxKind.Identifier */: + case 109 /* SyntaxKind.ThisKeyword */: + case 107 /* SyntaxKind.SuperKeyword */: + case 237 /* SyntaxKind.MetaProperty */: + return true; + case 211 /* SyntaxKind.PropertyAccessExpression */: + case 217 /* SyntaxKind.ParenthesizedExpression */: + case 236 /* SyntaxKind.NonNullExpression */: + return isNarrowableReference(expr.expression); + case 212 /* SyntaxKind.ElementAccessExpression */: + return (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && + isNarrowableReference(expr.expression); + case 227 /* SyntaxKind.BinaryExpression */: + return expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) || + ts.isAssignmentOperator(expr.operatorToken.kind) && ts.isLeftHandSideExpression(expr.left); + } + return false; } function containsNarrowableReference(expr) { return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); @@ -49166,6 +49181,7 @@ var ts; } function createFlowMutation(flags, antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node }); if (currentExceptionTarget) { addAntecedent(currentExceptionTarget, result); @@ -49174,6 +49190,7 @@ var ts; } function createFlowCall(antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; return initFlowNode({ flags: 512 /* FlowFlags.Call */, antecedent: antecedent, node: node }); } function finishFlowLabel(flow) { @@ -49339,6 +49356,7 @@ var ts; } } currentFlow = unreachableFlow; + hasFlowEffects = true; } function findActiveLabel(name) { for (var label = activeLabelList; label; label = label.next) { @@ -49353,6 +49371,7 @@ var ts; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; + hasFlowEffects = true; } } function bindBreakOrContinueStatement(node) { @@ -49658,8 +49677,12 @@ var ts; ts.isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindLogicalLikeExpression(node, currentTrueTarget, currentFalseTarget); @@ -49732,6 +49755,9 @@ var ts; var trueLabel = createBranchLabel(); var falseLabel = createBranchLabel(); var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); @@ -49742,6 +49768,8 @@ var ts; bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } function bindInitializedVariableFlow(node) { var name = !ts.isOmittedExpression(node) ? node.name : undefined; @@ -49863,8 +49891,11 @@ var ts; function bindOptionalChainFlow(node) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; bindOptionalChain(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindOptionalChain(node, currentTrueTarget, currentFalseTarget); @@ -52032,6 +52063,8 @@ var ts; var apparentArgumentCount; var constEnumRelate = new ts.Map(); var performanceFileName; + // Used only for linter, in non-strict typeChecker, it is always empty. + var qualifiedNameCache = new ts.Map(); // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. // for most of these, we perform the guard only on `checker` to avoid any possible @@ -52375,6 +52408,7 @@ var ts; getConstEnumRelate: function () { return constEnumRelate; }, clearConstEnumRelate: function () { constEnumRelate && constEnumRelate.clear(); }, deleteConstEnumRelate: function (path) { constEnumRelate && constEnumRelate.delete(path); }, + clearQualifiedNameCache: function () { qualifiedNameCache && qualifiedNameCache.clear(); }, }; function runWithInferenceBlockedFromSourceNode(node, fn) { var containingCall = ts.findAncestor(node, ts.isCallLikeExpression); @@ -54885,7 +54919,21 @@ var ts; } } function getFullyQualifiedName(symbol, containingLocation) { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); + if (containingLocation === undefined) { + var cachedQualifiedName = qualifiedNameCache.get(symbol); + if (cachedQualifiedName) { + return cachedQualifiedName; + } + } + var qualifiedName = getFullyQualifiedNameNoCache(symbol, containingLocation); + if (isTypeCheckerForLinter && containingLocation === undefined) { + qualifiedNameCache.set(symbol, qualifiedName); + } + return qualifiedName; + } + function getFullyQualifiedNameNoCache(symbol, containingLocation) { + return symbol.parent ? getFullyQualifiedNameNoCache(symbol.parent, containingLocation) + "." + symbolToString(symbol) : + symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); } function getContainingQualifiedNameNode(node) { while (ts.isQualifiedName(node.parent)) { @@ -56251,7 +56299,9 @@ var ts; function symbolToStringWorker(writer) { var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217 // add neverAsciiEscape for GH#39027 - var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ ? ts.createPrinter({ removeComments: true, neverAsciiEscape: true }) : ts.createPrinter({ removeComments: true }); + var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ + ? ts.createPrinterWithRemoveCommentsNeverAsciiEscape() + : ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, entity, /*sourceFile*/ sourceFile, writer); return writer; @@ -56269,7 +56319,7 @@ var ts; sigOutput = kind === 1 /* SignatureKind.Construct */ ? 180 /* SyntaxKind.ConstructSignature */ : 179 /* SyntaxKind.CallSignature */; } var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */); - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 return writer; @@ -56284,8 +56334,7 @@ var ts; return ts.Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. - var options = { removeComments: type !== unresolvedType }; - var printer = ts.createPrinter(options); + var printer = type !== unresolvedType ? ts.createPrinterWithRemoveComments() : ts.createPrinterWithDefaults(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); @@ -59361,7 +59410,7 @@ var ts; function typePredicateToStringWorker(writer) { var predicate = ts.factory.createTypePredicateNode(typePredicate.kind === 2 /* TypePredicateKind.AssertsThis */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createToken(130 /* SyntaxKind.AssertsKeyword */) : undefined, typePredicate.kind === 1 /* TypePredicateKind.Identifier */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createIdentifier(typePredicate.parameterName) : ts.factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */) // TODO: GH#18217 ); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, predicate, /*sourceFile*/ sourceFile, writer); return writer; @@ -65494,7 +65543,7 @@ var ts; origin = createOriginUnionOrIntersectionType(1048576 /* TypeFlags.Union */, reducedTypes); } } - var objectFlags = (includes & 36323363 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | + var objectFlags = (includes & 36323331 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | (includes & 2097152 /* TypeFlags.Intersection */ ? 16777216 /* ObjectFlags.ContainsIntersections */ : 0); return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments, origin); } @@ -65637,7 +65686,7 @@ var ts; var u = unionTypes_1[_i]; if (!containsType(u.types, type)) { var primitive = type.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : - type.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + type.flags & (32 /* TypeFlags.Enum */ | 256 /* TypeFlags.NumberLiteral */) ? numberType : type.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : type.flags & 8192 /* TypeFlags.UniqueESSymbol */ ? esSymbolType : undefined; @@ -65673,9 +65722,6 @@ var ts; } return false; } - function eachIsUnionContaining(types, flag) { - return ts.every(types, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); }); - } function removeFromEach(types, flag) { for (var i = 0; i < types.length; i++) { types[i] = filterType(types[i], function (t) { return !(t.flags & flag); }); @@ -65807,12 +65853,12 @@ var ts; // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 32768 /* TypeFlags.Undefined */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && t.types[0].flags & 32768 /* TypeFlags.Undefined */); })) { var undefinedOrMissingType = exactOptionalPropertyTypes && ts.some(typeSet, function (t) { return containsType(t.types, missingType); }) ? missingType : undefinedType; removeFromEach(typeSet, 32768 /* TypeFlags.Undefined */); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 65536 /* TypeFlags.Null */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && (t.types[0].flags & 65536 /* TypeFlags.Null */ || t.types[1].flags & 65536 /* TypeFlags.Null */)); })) { removeFromEach(typeSet, 65536 /* TypeFlags.Null */); result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } @@ -69565,6 +69611,20 @@ var ts; if (containsType(targetTypes, source)) { return -1 /* Ternary.True */; } + if (ts.getObjectFlags(target) & 32768 /* ObjectFlags.PrimitiveUnion */ && !(source.flags & 1024 /* TypeFlags.EnumLiteral */) && (source.flags & (128 /* TypeFlags.StringLiteral */ | 512 /* TypeFlags.BooleanLiteral */ | 2048 /* TypeFlags.BigIntLiteral */) || + (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & 256 /* TypeFlags.NumberLiteral */)) { + // When relating a literal type to a union of primitive types, we know the relation is false unless + // the union contains the base primitive type or the literal type in one of its fresh/regular forms. + // We exclude numeric literals for non-subtype relations because numeric literals are assignable to + // numeric enum literals with the same value. Similarly, we exclude enum literal types because + // identically named enum types are related (see isEmumTypeRelatedTo). + var alternateForm = source === source.regularType ? source.freshType : source.regularType; + var primitive = source.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : + source.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + source.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : + undefined; + return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? -1 /* Ternary.True */ : 0 /* Ternary.False */; + } var match = getMatchingUnionConstituentForType(target, source); if (match) { var related = isRelatedTo(source, match, 2 /* RecursionFlags.Target */, /*reportErrors*/ false); @@ -117535,6 +117595,14 @@ var ts; PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps"; PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit"; })(PipelinePhase || (PipelinePhase = {})); + /** @internal */ + ts.createPrinterWithDefaults = ts.memoize(function () { return createPrinter({}); }); + /** @internal */ + ts.createPrinterWithRemoveComments = ts.memoize(function () { return createPrinter({ removeComments: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsNeverAsciiEscape = ts.memoize(function () { return createPrinter({ removeComments: true, neverAsciiEscape: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon = ts.memoize(function () { return createPrinter({ removeComments: true, omitTrailingSemicolon: true }); }); function createPrinter(printerOptions, handlers) { if (printerOptions === void 0) { printerOptions = {}; } if (handlers === void 0) { handlers = {}; } @@ -136763,7 +136831,7 @@ var ts; function nodeToDisplayParts(node, enclosingDeclaration) { var file = enclosingDeclaration.getSourceFile(); return mapToDisplayParts(function (writer) { - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); printer.writeNode(4 /* EmitHint.Unspecified */, node, file, writer); }); } @@ -147492,7 +147560,7 @@ var ts; } if (text === undefined) { // get the text from printing the node on a single line without comments... - var printer_1 = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer_1 = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); text = ts.usingSingleLineStringWriter(function (writer) { return printer_1.writeNode(4 /* EmitHint.Unspecified */, node, node.getSourceFile(), writer); }); } return { text: text, pos: declName.getStart(), end: declName.getEnd() }; @@ -152761,7 +152829,7 @@ var ts; } function getTypeHelpItem(symbol, typeParameters, checker, enclosingDeclaration, sourceFile) { var typeSymbolDisplay = ts.symbolToDisplayParts(checker, symbol); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = typeParameters.map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var documentation = symbol.getDocumentationComment(checker); var tags = symbol.getJsDocTags(checker); @@ -152795,7 +152863,7 @@ var ts; } function itemInfoForTypeParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = (typeParameters || ts.emptyArray).map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)] : []; return checker.getExpandedParameters(candidateSignature).map(function (paramList) { @@ -152807,7 +152875,7 @@ var ts; }); } function itemInfoForParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var typeParameterParts = ts.mapToDisplayParts(function (writer) { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { var args = ts.factory.createNodeArray(candidateSignature.typeParameters.map(function (p) { return checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags); })); @@ -153110,8 +153178,7 @@ var ts; } function printTypeInSingleLine(type) { var flags = 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 1048576 /* TypeFormatFlags.AllowUniqueESSymbolType */ | 16384 /* TypeFormatFlags.UseAliasDefinedOutsideCurrentScope */; - var options = { removeComments: true }; - var printer = ts.createPrinter(options); + var printer = ts.createPrinterWithRemoveComments(); return ts.usingSingleLineStringWriter(function (writer) { var typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags, writer); ts.Debug.assertIsDefined(typeNode, "should always get typenode"); @@ -153656,7 +153723,6 @@ var ts; var hasAddedSymbolInfo = false; var isThisExpression = location.kind === 109 /* SyntaxKind.ThisKeyword */ && ts.isInExpressionContext(location) || ts.isThisInTypeQuery(location); var type; - var printer; var documentationFromAlias; var tagsFromAlias; var hasMultipleSignatures = false; @@ -154099,10 +154165,7 @@ var ts; } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags.length === 0 ? undefined : tags }; function getPrinter() { - if (!printer) { - printer = ts.createPrinter({ removeComments: true }); - } - return printer; + return ts.createPrinterWithRemoveComments(); } function prefixNextMeaning() { if (displayParts.length) { @@ -174244,6 +174307,9 @@ var ts; ts.PerformanceDotting.start("isProgramUptoDate"); if (ts.isProgramUptoDate(program, rootFileNames, newSettings, function (_path, fileName) { return host.getScriptVersion(fileName); }, function (fileName) { return compilerHost.fileExists(fileName); }, hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { ts.PerformanceDotting.stop("isProgramUptoDate"); + // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches; + // clear these caches to avoid affecting future compilations. + host.clearFileCache && host.clearFileCache(); return; } ts.PerformanceDotting.stop("isProgramUptoDate"); @@ -174287,6 +174353,7 @@ var ts; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); + host.clearFileCache && host.clearFileCache(); return; function getParsedCommandLine(fileName) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); @@ -181888,6 +181955,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { if (autofixable === void 0) { autofixable = false; } if (!TypeScriptLinter.strictMode && faultsAttrs[faultId].migratable) { @@ -183683,6 +183755,7 @@ var ts; ArkTSLinter_1_0.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_0.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_0.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_0.Utils.clearTypeChecker(); ArkTSLinter_1_0.Utils.clearTrueSymbolAtLocationCache(); @@ -187294,6 +187367,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { var _a, _b; if (autofixable === void 0) { autofixable = false; } @@ -190119,6 +190197,7 @@ var ts; ArkTSLinter_1_1.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_1.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_1.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.InteropTypescriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.Utils.clearTypeChecker(); diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 91e0b72abd5624416c4e6ef7ab42b418de2cf476..efcf2daeb02a600b7146edf05561ca251a140246 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -2543,6 +2543,7 @@ declare namespace ts { getConstEnumRelate?(): ESMap>; clearConstEnumRelate?(): void; deleteConstEnumRelate?(path: string): void; + clearQualifiedNameCache?(): void; } export enum NodeBuilderFlags { None = 0, @@ -6378,6 +6379,7 @@ declare namespace ts { shouldCompletionSortCustom?: boolean; uiProps?: string[]; clearProps?(): void; + clearFileCache?(): void; } type WithMetadata = T & { metadata?: unknown; @@ -9068,6 +9070,7 @@ declare namespace ts { skipArkTSStaticBlocksCheck: boolean; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void>; incrementCounters(node: Node | CommentRange, faultId: number, autofixable?: boolean, autofix?: Autofix[]): void; visitTSNode(node: Node): void; @@ -9686,6 +9689,7 @@ declare namespace ts { private compatibleSdkVersion; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void; name: string; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 9bc8f8f7b16f311fe9c296ea70691ef1adbcc52c..bbbdade3163e8713543a04fa88ece21dccb447f2 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -5420,7 +5420,7 @@ var ts; /* @internal */ TypeFlags[TypeFlags["IncludesInstantiable"] = 33554432] = "IncludesInstantiable"; /* @internal */ - TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323363] = "NotPrimitiveUnion"; + TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323331] = "NotPrimitiveUnion"; })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {})); // Types included in TypeFlags.ObjectFlagsType have an objectFlags property. Some ObjectFlags // are specific to certain types and reuse the same bit position. Those ObjectFlags require a check @@ -39313,7 +39313,7 @@ var ts; return withJSDoc(finishNode(node, pos), hasJSDoc); } function isSetLazy(identifier) { - // 1. import lazy { export } from "mod"; + // 1. import lazy { export } from "mod"; // 2. import lazy defaultExport from "mod"; // 3. import lazy defaultExport, { export, /* ... */ } from "mod"; return (identifier === null || identifier === void 0 ? void 0 : identifier.escapedText) === 'lazy' && @@ -48417,6 +48417,7 @@ var ts; var preSwitchCaseFlow; var activeLabelList; var hasExplicitReturn; + var hasFlowEffects; // state used for emit helpers var emitFlags; // If this file is an external module, then it is automatically in strict-mode according to @@ -48480,6 +48481,7 @@ var ts; currentExceptionTarget = undefined; activeLabelList = undefined; hasExplicitReturn = false; + hasFlowEffects = false; inAssignmentPattern = false; emitFlags = 0 /* NodeFlags.None */; } @@ -49040,8 +49042,8 @@ var ts; function isNarrowingExpression(expr) { switch (expr.kind) { case 79 /* SyntaxKind.Identifier */: - case 80 /* SyntaxKind.PrivateIdentifier */: case 109 /* SyntaxKind.ThisKeyword */: + return true; case 211 /* SyntaxKind.PropertyAccessExpression */: case 212 /* SyntaxKind.ElementAccessExpression */: return containsNarrowableReference(expr); @@ -49060,11 +49062,24 @@ var ts; return false; } function isNarrowableReference(expr) { - return ts.isDottedName(expr) - || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || ts.isBinaryExpression(expr) && expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) - || ts.isElementAccessExpression(expr) && (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || ts.isAssignmentExpression(expr) && isNarrowableReference(expr.left); + switch (expr.kind) { + case 79 /* SyntaxKind.Identifier */: + case 109 /* SyntaxKind.ThisKeyword */: + case 107 /* SyntaxKind.SuperKeyword */: + case 237 /* SyntaxKind.MetaProperty */: + return true; + case 211 /* SyntaxKind.PropertyAccessExpression */: + case 217 /* SyntaxKind.ParenthesizedExpression */: + case 236 /* SyntaxKind.NonNullExpression */: + return isNarrowableReference(expr.expression); + case 212 /* SyntaxKind.ElementAccessExpression */: + return (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && + isNarrowableReference(expr.expression); + case 227 /* SyntaxKind.BinaryExpression */: + return expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) || + ts.isAssignmentOperator(expr.operatorToken.kind) && ts.isLeftHandSideExpression(expr.left); + } + return false; } function containsNarrowableReference(expr) { return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); @@ -49166,6 +49181,7 @@ var ts; } function createFlowMutation(flags, antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node }); if (currentExceptionTarget) { addAntecedent(currentExceptionTarget, result); @@ -49174,6 +49190,7 @@ var ts; } function createFlowCall(antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; return initFlowNode({ flags: 512 /* FlowFlags.Call */, antecedent: antecedent, node: node }); } function finishFlowLabel(flow) { @@ -49339,6 +49356,7 @@ var ts; } } currentFlow = unreachableFlow; + hasFlowEffects = true; } function findActiveLabel(name) { for (var label = activeLabelList; label; label = label.next) { @@ -49353,6 +49371,7 @@ var ts; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; + hasFlowEffects = true; } } function bindBreakOrContinueStatement(node) { @@ -49658,8 +49677,12 @@ var ts; ts.isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindLogicalLikeExpression(node, currentTrueTarget, currentFalseTarget); @@ -49732,6 +49755,9 @@ var ts; var trueLabel = createBranchLabel(); var falseLabel = createBranchLabel(); var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); @@ -49742,6 +49768,8 @@ var ts; bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } function bindInitializedVariableFlow(node) { var name = !ts.isOmittedExpression(node) ? node.name : undefined; @@ -49863,8 +49891,11 @@ var ts; function bindOptionalChainFlow(node) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; bindOptionalChain(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindOptionalChain(node, currentTrueTarget, currentFalseTarget); @@ -52032,6 +52063,8 @@ var ts; var apparentArgumentCount; var constEnumRelate = new ts.Map(); var performanceFileName; + // Used only for linter, in non-strict typeChecker, it is always empty. + var qualifiedNameCache = new ts.Map(); // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. // for most of these, we perform the guard only on `checker` to avoid any possible @@ -52375,6 +52408,7 @@ var ts; getConstEnumRelate: function () { return constEnumRelate; }, clearConstEnumRelate: function () { constEnumRelate && constEnumRelate.clear(); }, deleteConstEnumRelate: function (path) { constEnumRelate && constEnumRelate.delete(path); }, + clearQualifiedNameCache: function () { qualifiedNameCache && qualifiedNameCache.clear(); }, }; function runWithInferenceBlockedFromSourceNode(node, fn) { var containingCall = ts.findAncestor(node, ts.isCallLikeExpression); @@ -54885,7 +54919,21 @@ var ts; } } function getFullyQualifiedName(symbol, containingLocation) { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); + if (containingLocation === undefined) { + var cachedQualifiedName = qualifiedNameCache.get(symbol); + if (cachedQualifiedName) { + return cachedQualifiedName; + } + } + var qualifiedName = getFullyQualifiedNameNoCache(symbol, containingLocation); + if (isTypeCheckerForLinter && containingLocation === undefined) { + qualifiedNameCache.set(symbol, qualifiedName); + } + return qualifiedName; + } + function getFullyQualifiedNameNoCache(symbol, containingLocation) { + return symbol.parent ? getFullyQualifiedNameNoCache(symbol.parent, containingLocation) + "." + symbolToString(symbol) : + symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); } function getContainingQualifiedNameNode(node) { while (ts.isQualifiedName(node.parent)) { @@ -56251,7 +56299,9 @@ var ts; function symbolToStringWorker(writer) { var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217 // add neverAsciiEscape for GH#39027 - var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ ? ts.createPrinter({ removeComments: true, neverAsciiEscape: true }) : ts.createPrinter({ removeComments: true }); + var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ + ? ts.createPrinterWithRemoveCommentsNeverAsciiEscape() + : ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, entity, /*sourceFile*/ sourceFile, writer); return writer; @@ -56269,7 +56319,7 @@ var ts; sigOutput = kind === 1 /* SignatureKind.Construct */ ? 180 /* SyntaxKind.ConstructSignature */ : 179 /* SyntaxKind.CallSignature */; } var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */); - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 return writer; @@ -56284,8 +56334,7 @@ var ts; return ts.Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. - var options = { removeComments: type !== unresolvedType }; - var printer = ts.createPrinter(options); + var printer = type !== unresolvedType ? ts.createPrinterWithRemoveComments() : ts.createPrinterWithDefaults(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); @@ -59361,7 +59410,7 @@ var ts; function typePredicateToStringWorker(writer) { var predicate = ts.factory.createTypePredicateNode(typePredicate.kind === 2 /* TypePredicateKind.AssertsThis */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createToken(130 /* SyntaxKind.AssertsKeyword */) : undefined, typePredicate.kind === 1 /* TypePredicateKind.Identifier */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createIdentifier(typePredicate.parameterName) : ts.factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */) // TODO: GH#18217 ); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, predicate, /*sourceFile*/ sourceFile, writer); return writer; @@ -65494,7 +65543,7 @@ var ts; origin = createOriginUnionOrIntersectionType(1048576 /* TypeFlags.Union */, reducedTypes); } } - var objectFlags = (includes & 36323363 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | + var objectFlags = (includes & 36323331 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | (includes & 2097152 /* TypeFlags.Intersection */ ? 16777216 /* ObjectFlags.ContainsIntersections */ : 0); return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments, origin); } @@ -65637,7 +65686,7 @@ var ts; var u = unionTypes_1[_i]; if (!containsType(u.types, type)) { var primitive = type.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : - type.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + type.flags & (32 /* TypeFlags.Enum */ | 256 /* TypeFlags.NumberLiteral */) ? numberType : type.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : type.flags & 8192 /* TypeFlags.UniqueESSymbol */ ? esSymbolType : undefined; @@ -65673,9 +65722,6 @@ var ts; } return false; } - function eachIsUnionContaining(types, flag) { - return ts.every(types, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); }); - } function removeFromEach(types, flag) { for (var i = 0; i < types.length; i++) { types[i] = filterType(types[i], function (t) { return !(t.flags & flag); }); @@ -65807,12 +65853,12 @@ var ts; // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 32768 /* TypeFlags.Undefined */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && t.types[0].flags & 32768 /* TypeFlags.Undefined */); })) { var undefinedOrMissingType = exactOptionalPropertyTypes && ts.some(typeSet, function (t) { return containsType(t.types, missingType); }) ? missingType : undefinedType; removeFromEach(typeSet, 32768 /* TypeFlags.Undefined */); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 65536 /* TypeFlags.Null */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && (t.types[0].flags & 65536 /* TypeFlags.Null */ || t.types[1].flags & 65536 /* TypeFlags.Null */)); })) { removeFromEach(typeSet, 65536 /* TypeFlags.Null */); result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } @@ -69565,6 +69611,20 @@ var ts; if (containsType(targetTypes, source)) { return -1 /* Ternary.True */; } + if (ts.getObjectFlags(target) & 32768 /* ObjectFlags.PrimitiveUnion */ && !(source.flags & 1024 /* TypeFlags.EnumLiteral */) && (source.flags & (128 /* TypeFlags.StringLiteral */ | 512 /* TypeFlags.BooleanLiteral */ | 2048 /* TypeFlags.BigIntLiteral */) || + (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & 256 /* TypeFlags.NumberLiteral */)) { + // When relating a literal type to a union of primitive types, we know the relation is false unless + // the union contains the base primitive type or the literal type in one of its fresh/regular forms. + // We exclude numeric literals for non-subtype relations because numeric literals are assignable to + // numeric enum literals with the same value. Similarly, we exclude enum literal types because + // identically named enum types are related (see isEmumTypeRelatedTo). + var alternateForm = source === source.regularType ? source.freshType : source.regularType; + var primitive = source.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : + source.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + source.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : + undefined; + return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? -1 /* Ternary.True */ : 0 /* Ternary.False */; + } var match = getMatchingUnionConstituentForType(target, source); if (match) { var related = isRelatedTo(source, match, 2 /* RecursionFlags.Target */, /*reportErrors*/ false); @@ -117535,6 +117595,14 @@ var ts; PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps"; PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit"; })(PipelinePhase || (PipelinePhase = {})); + /** @internal */ + ts.createPrinterWithDefaults = ts.memoize(function () { return createPrinter({}); }); + /** @internal */ + ts.createPrinterWithRemoveComments = ts.memoize(function () { return createPrinter({ removeComments: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsNeverAsciiEscape = ts.memoize(function () { return createPrinter({ removeComments: true, neverAsciiEscape: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon = ts.memoize(function () { return createPrinter({ removeComments: true, omitTrailingSemicolon: true }); }); function createPrinter(printerOptions, handlers) { if (printerOptions === void 0) { printerOptions = {}; } if (handlers === void 0) { handlers = {}; } @@ -136763,7 +136831,7 @@ var ts; function nodeToDisplayParts(node, enclosingDeclaration) { var file = enclosingDeclaration.getSourceFile(); return mapToDisplayParts(function (writer) { - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); printer.writeNode(4 /* EmitHint.Unspecified */, node, file, writer); }); } @@ -147492,7 +147560,7 @@ var ts; } if (text === undefined) { // get the text from printing the node on a single line without comments... - var printer_1 = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer_1 = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); text = ts.usingSingleLineStringWriter(function (writer) { return printer_1.writeNode(4 /* EmitHint.Unspecified */, node, node.getSourceFile(), writer); }); } return { text: text, pos: declName.getStart(), end: declName.getEnd() }; @@ -152761,7 +152829,7 @@ var ts; } function getTypeHelpItem(symbol, typeParameters, checker, enclosingDeclaration, sourceFile) { var typeSymbolDisplay = ts.symbolToDisplayParts(checker, symbol); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = typeParameters.map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var documentation = symbol.getDocumentationComment(checker); var tags = symbol.getJsDocTags(checker); @@ -152795,7 +152863,7 @@ var ts; } function itemInfoForTypeParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var parameters = (typeParameters || ts.emptyArray).map(function (t) { return createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer); }); var thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)] : []; return checker.getExpandedParameters(candidateSignature).map(function (paramList) { @@ -152807,7 +152875,7 @@ var ts; }); } function itemInfoForParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) { - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var typeParameterParts = ts.mapToDisplayParts(function (writer) { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { var args = ts.factory.createNodeArray(candidateSignature.typeParameters.map(function (p) { return checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags); })); @@ -153110,8 +153178,7 @@ var ts; } function printTypeInSingleLine(type) { var flags = 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 1048576 /* TypeFormatFlags.AllowUniqueESSymbolType */ | 16384 /* TypeFormatFlags.UseAliasDefinedOutsideCurrentScope */; - var options = { removeComments: true }; - var printer = ts.createPrinter(options); + var printer = ts.createPrinterWithRemoveComments(); return ts.usingSingleLineStringWriter(function (writer) { var typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags, writer); ts.Debug.assertIsDefined(typeNode, "should always get typenode"); @@ -153656,7 +153723,6 @@ var ts; var hasAddedSymbolInfo = false; var isThisExpression = location.kind === 109 /* SyntaxKind.ThisKeyword */ && ts.isInExpressionContext(location) || ts.isThisInTypeQuery(location); var type; - var printer; var documentationFromAlias; var tagsFromAlias; var hasMultipleSignatures = false; @@ -154099,10 +154165,7 @@ var ts; } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags.length === 0 ? undefined : tags }; function getPrinter() { - if (!printer) { - printer = ts.createPrinter({ removeComments: true }); - } - return printer; + return ts.createPrinterWithRemoveComments(); } function prefixNextMeaning() { if (displayParts.length) { @@ -174244,6 +174307,9 @@ var ts; ts.PerformanceDotting.start("isProgramUptoDate"); if (ts.isProgramUptoDate(program, rootFileNames, newSettings, function (_path, fileName) { return host.getScriptVersion(fileName); }, function (fileName) { return compilerHost.fileExists(fileName); }, hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { ts.PerformanceDotting.stop("isProgramUptoDate"); + // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches; + // clear these caches to avoid affecting future compilations. + host.clearFileCache && host.clearFileCache(); return; } ts.PerformanceDotting.stop("isProgramUptoDate"); @@ -174287,6 +174353,7 @@ var ts; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); + host.clearFileCache && host.clearFileCache(); return; function getParsedCommandLine(fileName) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); @@ -181888,6 +181955,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { if (autofixable === void 0) { autofixable = false; } if (!TypeScriptLinter.strictMode && faultsAttrs[faultId].migratable) { @@ -183683,6 +183755,7 @@ var ts; ArkTSLinter_1_0.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_0.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_0.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_0.Utils.clearTypeChecker(); ArkTSLinter_1_0.Utils.clearTrueSymbolAtLocationCache(); @@ -187294,6 +187367,11 @@ var ts; TypeScriptLinter.clearTsTypeChecker = function () { TypeScriptLinter.tsTypeChecker = {}; }; + TypeScriptLinter.clearQualifiedNameCache = function () { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + }; TypeScriptLinter.prototype.incrementCounters = function (node, faultId, autofixable, autofix) { var _a, _b; if (autofixable === void 0) { autofixable = false; } @@ -190119,6 +190197,7 @@ var ts; ArkTSLinter_1_1.runArkTSLinter = runArkTSLinter; // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences() { + ArkTSLinter_1_1.TypeScriptLinter.clearQualifiedNameCache(); ArkTSLinter_1_1.TypeScriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.InteropTypescriptLinter.clearTsTypeChecker(); ArkTSLinter_1_1.Utils.clearTypeChecker(); diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index e2cfecc552729c625c7fb6dd08dc4cb0672792ea..1ab6419fcf21f882d01e97b1f50e829d6a4b3517 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -5410,7 +5410,7 @@ var ts; /* @internal */ TypeFlags[TypeFlags["IncludesInstantiable"] = 33554432] = "IncludesInstantiable"; /* @internal */ - TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323363] = "NotPrimitiveUnion"; + TypeFlags[TypeFlags["NotPrimitiveUnion"] = 36323331] = "NotPrimitiveUnion"; })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {})); // Types included in TypeFlags.ObjectFlagsType have an objectFlags property. Some ObjectFlags // are specific to certain types and reuse the same bit position. Those ObjectFlags require a check @@ -39303,7 +39303,7 @@ var ts; return withJSDoc(finishNode(node, pos), hasJSDoc); } function isSetLazy(identifier) { - // 1. import lazy { export } from "mod"; + // 1. import lazy { export } from "mod"; // 2. import lazy defaultExport from "mod"; // 3. import lazy defaultExport, { export, /* ... */ } from "mod"; return (identifier === null || identifier === void 0 ? void 0 : identifier.escapedText) === 'lazy' && @@ -48407,6 +48407,7 @@ var ts; var preSwitchCaseFlow; var activeLabelList; var hasExplicitReturn; + var hasFlowEffects; // state used for emit helpers var emitFlags; // If this file is an external module, then it is automatically in strict-mode according to @@ -48470,6 +48471,7 @@ var ts; currentExceptionTarget = undefined; activeLabelList = undefined; hasExplicitReturn = false; + hasFlowEffects = false; inAssignmentPattern = false; emitFlags = 0 /* NodeFlags.None */; } @@ -49030,8 +49032,8 @@ var ts; function isNarrowingExpression(expr) { switch (expr.kind) { case 79 /* SyntaxKind.Identifier */: - case 80 /* SyntaxKind.PrivateIdentifier */: case 109 /* SyntaxKind.ThisKeyword */: + return true; case 211 /* SyntaxKind.PropertyAccessExpression */: case 212 /* SyntaxKind.ElementAccessExpression */: return containsNarrowableReference(expr); @@ -49050,11 +49052,24 @@ var ts; return false; } function isNarrowableReference(expr) { - return ts.isDottedName(expr) - || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || ts.isBinaryExpression(expr) && expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) - || ts.isElementAccessExpression(expr) && (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || ts.isAssignmentExpression(expr) && isNarrowableReference(expr.left); + switch (expr.kind) { + case 79 /* SyntaxKind.Identifier */: + case 109 /* SyntaxKind.ThisKeyword */: + case 107 /* SyntaxKind.SuperKeyword */: + case 237 /* SyntaxKind.MetaProperty */: + return true; + case 211 /* SyntaxKind.PropertyAccessExpression */: + case 217 /* SyntaxKind.ParenthesizedExpression */: + case 236 /* SyntaxKind.NonNullExpression */: + return isNarrowableReference(expr.expression); + case 212 /* SyntaxKind.ElementAccessExpression */: + return (ts.isStringOrNumericLiteralLike(expr.argumentExpression) || ts.isEntityNameExpression(expr.argumentExpression)) && + isNarrowableReference(expr.expression); + case 227 /* SyntaxKind.BinaryExpression */: + return expr.operatorToken.kind === 27 /* SyntaxKind.CommaToken */ && isNarrowableReference(expr.right) || + ts.isAssignmentOperator(expr.operatorToken.kind) && ts.isLeftHandSideExpression(expr.left); + } + return false; } function containsNarrowableReference(expr) { return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); @@ -49156,6 +49171,7 @@ var ts; } function createFlowMutation(flags, antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node }); if (currentExceptionTarget) { addAntecedent(currentExceptionTarget, result); @@ -49164,6 +49180,7 @@ var ts; } function createFlowCall(antecedent, node) { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; return initFlowNode({ flags: 512 /* FlowFlags.Call */, antecedent: antecedent, node: node }); } function finishFlowLabel(flow) { @@ -49329,6 +49346,7 @@ var ts; } } currentFlow = unreachableFlow; + hasFlowEffects = true; } function findActiveLabel(name) { for (var label = activeLabelList; label; label = label.next) { @@ -49343,6 +49361,7 @@ var ts; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; + hasFlowEffects = true; } } function bindBreakOrContinueStatement(node) { @@ -49648,8 +49667,12 @@ var ts; ts.isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindLogicalLikeExpression(node, currentTrueTarget, currentFalseTarget); @@ -49722,6 +49745,9 @@ var ts; var trueLabel = createBranchLabel(); var falseLabel = createBranchLabel(); var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); @@ -49732,6 +49758,8 @@ var ts; bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } function bindInitializedVariableFlow(node) { var name = !ts.isOmittedExpression(node) ? node.name : undefined; @@ -49853,8 +49881,11 @@ var ts; function bindOptionalChainFlow(node) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); + var saveCurrentFlow = currentFlow; + var saveHasFlowEffects = hasFlowEffects; bindOptionalChain(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects || (hasFlowEffects = saveHasFlowEffects); } else { bindOptionalChain(node, currentTrueTarget, currentFalseTarget); @@ -52022,6 +52053,8 @@ var ts; var apparentArgumentCount; var constEnumRelate = new ts.Map(); var performanceFileName; + // Used only for linter, in non-strict typeChecker, it is always empty. + var qualifiedNameCache = new ts.Map(); // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. // for most of these, we perform the guard only on `checker` to avoid any possible @@ -52365,6 +52398,7 @@ var ts; getConstEnumRelate: function () { return constEnumRelate; }, clearConstEnumRelate: function () { constEnumRelate && constEnumRelate.clear(); }, deleteConstEnumRelate: function (path) { constEnumRelate && constEnumRelate.delete(path); }, + clearQualifiedNameCache: function () { qualifiedNameCache && qualifiedNameCache.clear(); }, }; function runWithInferenceBlockedFromSourceNode(node, fn) { var containingCall = ts.findAncestor(node, ts.isCallLikeExpression); @@ -54875,7 +54909,21 @@ var ts; } } function getFullyQualifiedName(symbol, containingLocation) { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); + if (containingLocation === undefined) { + var cachedQualifiedName = qualifiedNameCache.get(symbol); + if (cachedQualifiedName) { + return cachedQualifiedName; + } + } + var qualifiedName = getFullyQualifiedNameNoCache(symbol, containingLocation); + if (isTypeCheckerForLinter && containingLocation === undefined) { + qualifiedNameCache.set(symbol, qualifiedName); + } + return qualifiedName; + } + function getFullyQualifiedNameNoCache(symbol, containingLocation) { + return symbol.parent ? getFullyQualifiedNameNoCache(symbol.parent, containingLocation) + "." + symbolToString(symbol) : + symbolToString(symbol, containingLocation, /*meaning*/ undefined, 32 /* SymbolFormatFlags.DoNotIncludeSymbolChain */ | 4 /* SymbolFormatFlags.AllowAnyNodeKind */); } function getContainingQualifiedNameNode(node) { while (ts.isQualifiedName(node.parent)) { @@ -56241,7 +56289,9 @@ var ts; function symbolToStringWorker(writer) { var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217 // add neverAsciiEscape for GH#39027 - var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ ? ts.createPrinter({ removeComments: true, neverAsciiEscape: true }) : ts.createPrinter({ removeComments: true }); + var printer = (enclosingDeclaration === null || enclosingDeclaration === void 0 ? void 0 : enclosingDeclaration.kind) === 314 /* SyntaxKind.SourceFile */ + ? ts.createPrinterWithRemoveCommentsNeverAsciiEscape() + : ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, entity, /*sourceFile*/ sourceFile, writer); return writer; @@ -56259,7 +56309,7 @@ var ts; sigOutput = kind === 1 /* SignatureKind.Construct */ ? 180 /* SyntaxKind.ConstructSignature */ : 179 /* SyntaxKind.CallSignature */; } var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */); - var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + var printer = ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 return writer; @@ -56274,8 +56324,7 @@ var ts; return ts.Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. - var options = { removeComments: type !== unresolvedType }; - var printer = ts.createPrinter(options); + var printer = type !== unresolvedType ? ts.createPrinterWithRemoveComments() : ts.createPrinterWithDefaults(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); @@ -59351,7 +59400,7 @@ var ts; function typePredicateToStringWorker(writer) { var predicate = ts.factory.createTypePredicateNode(typePredicate.kind === 2 /* TypePredicateKind.AssertsThis */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createToken(130 /* SyntaxKind.AssertsKeyword */) : undefined, typePredicate.kind === 1 /* TypePredicateKind.Identifier */ || typePredicate.kind === 3 /* TypePredicateKind.AssertsIdentifier */ ? ts.factory.createIdentifier(typePredicate.parameterName) : ts.factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* NodeBuilderFlags.IgnoreErrors */ | 512 /* NodeBuilderFlags.WriteTypeParametersInQualifiedName */) // TODO: GH#18217 ); - var printer = ts.createPrinter({ removeComments: true }); + var printer = ts.createPrinterWithRemoveComments(); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* EmitHint.Unspecified */, predicate, /*sourceFile*/ sourceFile, writer); return writer; @@ -65484,7 +65533,7 @@ var ts; origin = createOriginUnionOrIntersectionType(1048576 /* TypeFlags.Union */, reducedTypes); } } - var objectFlags = (includes & 36323363 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | + var objectFlags = (includes & 36323331 /* TypeFlags.NotPrimitiveUnion */ ? 0 : 32768 /* ObjectFlags.PrimitiveUnion */) | (includes & 2097152 /* TypeFlags.Intersection */ ? 16777216 /* ObjectFlags.ContainsIntersections */ : 0); return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments, origin); } @@ -65627,7 +65676,7 @@ var ts; var u = unionTypes_1[_i]; if (!containsType(u.types, type)) { var primitive = type.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : - type.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + type.flags & (32 /* TypeFlags.Enum */ | 256 /* TypeFlags.NumberLiteral */) ? numberType : type.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : type.flags & 8192 /* TypeFlags.UniqueESSymbol */ ? esSymbolType : undefined; @@ -65663,9 +65712,6 @@ var ts; } return false; } - function eachIsUnionContaining(types, flag) { - return ts.every(types, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); }); - } function removeFromEach(types, flag) { for (var i = 0; i < types.length; i++) { types[i] = filterType(types[i], function (t) { return !(t.flags & flag); }); @@ -65797,12 +65843,12 @@ var ts; // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 32768 /* TypeFlags.Undefined */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && t.types[0].flags & 32768 /* TypeFlags.Undefined */); })) { var undefinedOrMissingType = exactOptionalPropertyTypes && ts.some(typeSet, function (t) { return containsType(t.types, missingType); }) ? missingType : undefinedType; removeFromEach(typeSet, 32768 /* TypeFlags.Undefined */); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, 65536 /* TypeFlags.Null */)) { + else if (ts.every(typeSet, function (t) { return !!(t.flags & 1048576 /* TypeFlags.Union */ && (t.types[0].flags & 65536 /* TypeFlags.Null */ || t.types[1].flags & 65536 /* TypeFlags.Null */)); })) { removeFromEach(typeSet, 65536 /* TypeFlags.Null */); result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* UnionReduction.Literal */, aliasSymbol, aliasTypeArguments); } @@ -69555,6 +69601,20 @@ var ts; if (containsType(targetTypes, source)) { return -1 /* Ternary.True */; } + if (ts.getObjectFlags(target) & 32768 /* ObjectFlags.PrimitiveUnion */ && !(source.flags & 1024 /* TypeFlags.EnumLiteral */) && (source.flags & (128 /* TypeFlags.StringLiteral */ | 512 /* TypeFlags.BooleanLiteral */ | 2048 /* TypeFlags.BigIntLiteral */) || + (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & 256 /* TypeFlags.NumberLiteral */)) { + // When relating a literal type to a union of primitive types, we know the relation is false unless + // the union contains the base primitive type or the literal type in one of its fresh/regular forms. + // We exclude numeric literals for non-subtype relations because numeric literals are assignable to + // numeric enum literals with the same value. Similarly, we exclude enum literal types because + // identically named enum types are related (see isEmumTypeRelatedTo). + var alternateForm = source === source.regularType ? source.freshType : source.regularType; + var primitive = source.flags & 128 /* TypeFlags.StringLiteral */ ? stringType : + source.flags & 256 /* TypeFlags.NumberLiteral */ ? numberType : + source.flags & 2048 /* TypeFlags.BigIntLiteral */ ? bigintType : + undefined; + return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? -1 /* Ternary.True */ : 0 /* Ternary.False */; + } var match = getMatchingUnionConstituentForType(target, source); if (match) { var related = isRelatedTo(source, match, 2 /* RecursionFlags.Target */, /*reportErrors*/ false); @@ -117525,6 +117585,14 @@ var ts; PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps"; PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit"; })(PipelinePhase || (PipelinePhase = {})); + /** @internal */ + ts.createPrinterWithDefaults = ts.memoize(function () { return createPrinter({}); }); + /** @internal */ + ts.createPrinterWithRemoveComments = ts.memoize(function () { return createPrinter({ removeComments: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsNeverAsciiEscape = ts.memoize(function () { return createPrinter({ removeComments: true, neverAsciiEscape: true }); }); + /** @internal */ + ts.createPrinterWithRemoveCommentsOmitTrailingSemicolon = ts.memoize(function () { return createPrinter({ removeComments: true, omitTrailingSemicolon: true }); }); function createPrinter(printerOptions, handlers) { if (printerOptions === void 0) { printerOptions = {}; } if (handlers === void 0) { handlers = {}; } diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 10946675ffa41869df6a07bc8744985075c66971..23dde575cadbe4c040dbe814d43c7d52ee8d67c8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -207,6 +207,7 @@ namespace ts { let preSwitchCaseFlow: FlowNode | undefined; let activeLabelList: ActiveLabel | undefined; let hasExplicitReturn: boolean; + var hasFlowEffects: boolean; // state used for emit helpers let emitFlags: NodeFlags; @@ -282,6 +283,7 @@ namespace ts { currentExceptionTarget = undefined; activeLabelList = undefined; hasExplicitReturn = false; + hasFlowEffects = false; inAssignmentPattern = false; emitFlags = NodeFlags.None; } @@ -875,8 +877,8 @@ namespace ts { function isNarrowingExpression(expr: Expression): boolean { switch (expr.kind) { case SyntaxKind.Identifier: - case SyntaxKind.PrivateIdentifier: case SyntaxKind.ThisKeyword: + return true; case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: return containsNarrowableReference(expr); @@ -896,11 +898,24 @@ namespace ts { } function isNarrowableReference(expr: Expression): boolean { - return isDottedName(expr) - || (isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) - || isBinaryExpression(expr) && expr.operatorToken.kind === SyntaxKind.CommaToken && isNarrowableReference(expr.right) - || isElementAccessExpression(expr) && (isStringOrNumericLiteralLike(expr.argumentExpression) || isEntityNameExpression(expr.argumentExpression)) && isNarrowableReference(expr.expression) - || isAssignmentExpression(expr) && isNarrowableReference(expr.left); + switch (expr.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.ThisKeyword: + case SyntaxKind.SuperKeyword: + case SyntaxKind.MetaProperty: + return true; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ParenthesizedExpression: + case SyntaxKind.NonNullExpression: + return isNarrowableReference((expr as PropertyAccessExpression | ParenthesizedExpression | NonNullExpression).expression); + case SyntaxKind.ElementAccessExpression: + return (isStringOrNumericLiteralLike((expr as ElementAccessExpression).argumentExpression) || isEntityNameExpression((expr as ElementAccessExpression).argumentExpression)) && + isNarrowableReference((expr as ElementAccessExpression).expression); + case SyntaxKind.BinaryExpression: + return (expr as BinaryExpression).operatorToken.kind === SyntaxKind.CommaToken && isNarrowableReference((expr as BinaryExpression).right) || + isAssignmentOperator((expr as BinaryExpression).operatorToken.kind) && isLeftHandSideExpression((expr as BinaryExpression).left); + } + return false; } function containsNarrowableReference(expr: Expression): boolean { @@ -1014,6 +1029,7 @@ namespace ts { function createFlowMutation(flags: FlowFlags, antecedent: FlowNode, node: Expression | VariableDeclaration | ArrayBindingElement): FlowNode { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; const result = initFlowNode({ flags, antecedent, node }); if (currentExceptionTarget) { addAntecedent(currentExceptionTarget, result); @@ -1023,6 +1039,7 @@ namespace ts { function createFlowCall(antecedent: FlowNode, node: CallExpression): FlowNode { setFlowNodeReferenced(antecedent); + hasFlowEffects = true; return initFlowNode({ flags: FlowFlags.Call, antecedent, node }); } @@ -1204,6 +1221,7 @@ namespace ts { } } currentFlow = unreachableFlow; + hasFlowEffects = true; } function findActiveLabel(name: __String) { @@ -1220,6 +1238,7 @@ namespace ts { if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; + hasFlowEffects = true; } } @@ -1548,8 +1567,12 @@ namespace ts { isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { const postExpressionLabel = createBranchLabel(); + const saveCurrentFlow = currentFlow; + const saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects ||= saveHasFlowEffects; } else { bindLogicalLikeExpression(node, currentTrueTarget!, currentFalseTarget!); @@ -1629,6 +1652,9 @@ namespace ts { const trueLabel = createBranchLabel(); const falseLabel = createBranchLabel(); const postExpressionLabel = createBranchLabel(); + const saveCurrentFlow = currentFlow; + const saveHasFlowEffects = hasFlowEffects; + hasFlowEffects = false; bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); @@ -1639,6 +1665,8 @@ namespace ts { bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects ||= saveHasFlowEffects; } function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) { @@ -1770,8 +1798,11 @@ namespace ts { function bindOptionalChainFlow(node: OptionalChain) { if (isTopLevelLogicalExpression(node)) { const postExpressionLabel = createBranchLabel(); + const saveCurrentFlow = currentFlow; + const saveHasFlowEffects = hasFlowEffects; bindOptionalChain(node, postExpressionLabel, postExpressionLabel); - currentFlow = finishFlowLabel(postExpressionLabel); + currentFlow = hasFlowEffects ? finishFlowLabel(postExpressionLabel) : saveCurrentFlow; + hasFlowEffects ||= saveHasFlowEffects; } else { bindOptionalChain(node, currentTrueTarget!, currentFalseTarget!); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e8504920ae135d3910f1e148d7a5d179e9a9982b..f48a14a146a4505c897ded21e535bc7ca743aeed 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -408,6 +408,8 @@ namespace ts { let constEnumRelate: ESMap> = new Map(); let performanceFileName: string; + // Used only for linter, in non-strict typeChecker, it is always empty. + let qualifiedNameCache: ESMap = new Map(); // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. @@ -763,6 +765,7 @@ namespace ts { getConstEnumRelate: () => constEnumRelate, clearConstEnumRelate: () => {constEnumRelate && constEnumRelate.clear()}, deleteConstEnumRelate: (path: string) => {constEnumRelate && constEnumRelate.delete(path)}, + clearQualifiedNameCache: () => {qualifiedNameCache && qualifiedNameCache.clear()}, }; function runWithInferenceBlockedFromSourceNode(node: Node | undefined, fn: () => T): T { @@ -3503,7 +3506,23 @@ namespace ts { } function getFullyQualifiedName(symbol: Symbol, containingLocation?: Node): string { - return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, SymbolFormatFlags.DoNotIncludeSymbolChain | SymbolFormatFlags.AllowAnyNodeKind); + if (containingLocation === undefined) { + const cachedQualifiedName: string | undefined = qualifiedNameCache.get(symbol); + if (cachedQualifiedName) { + return cachedQualifiedName; + } + } + let qualifiedName: string = getFullyQualifiedNameNoCache(symbol, containingLocation); + if (isTypeCheckerForLinter && containingLocation === undefined) { + qualifiedNameCache.set(symbol, qualifiedName); + } + return qualifiedName; + } + + function getFullyQualifiedNameNoCache(symbol: Symbol, containingLocation?: Node): string { + return symbol.parent ? getFullyQualifiedNameNoCache(symbol.parent, containingLocation) + "." + symbolToString(symbol) : + symbolToString(symbol, containingLocation, /*meaning*/ undefined, + SymbolFormatFlags.DoNotIncludeSymbolChain | SymbolFormatFlags.AllowAnyNodeKind); } function getContainingQualifiedNameNode(node: QualifiedName) { @@ -5026,7 +5045,9 @@ namespace ts { function symbolToStringWorker(writer: EmitTextWriter) { const entity = builder(symbol, meaning!, enclosingDeclaration, nodeFlags)!; // TODO: GH#18217 // add neverAsciiEscape for GH#39027 - const printer = enclosingDeclaration?.kind === SyntaxKind.SourceFile ? createPrinter({ removeComments: true, neverAsciiEscape: true }) : createPrinter({ removeComments: true }); + const printer = enclosingDeclaration?.kind === SyntaxKind.SourceFile + ? createPrinterWithRemoveCommentsNeverAsciiEscape() + : createPrinterWithRemoveComments(); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); printer.writeNode(EmitHint.Unspecified, entity, /*sourceFile*/ sourceFile, writer); return writer; @@ -5045,7 +5066,7 @@ namespace ts { sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructSignature : SyntaxKind.CallSignature; } const sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName); - const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + const printer = createPrinterWithRemoveCommentsOmitTrailingSemicolon(); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); printer.writeNode(EmitHint.Unspecified, sig!, /*sourceFile*/ sourceFile, getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217 return writer; @@ -5058,8 +5079,7 @@ namespace ts { if (typeNode === undefined) return Debug.fail("should always get typenode"); // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. // Otherwise, we always strip comments out. - const options = { removeComments: type !== unresolvedType }; - const printer = createPrinter(options); + const printer = type !== unresolvedType ? createPrinterWithRemoveComments() : createPrinterWithDefaults(); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer); const result = writer.getText(); @@ -8577,7 +8597,7 @@ namespace ts { typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? factory.createIdentifier(typePredicate.parameterName) : factory.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217 ); - const printer = createPrinter({ removeComments: true }); + const printer = createPrinterWithRemoveComments(); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); printer.writeNode(EmitHint.Unspecified, predicate, /*sourceFile*/ sourceFile, writer); return writer; @@ -15311,7 +15331,7 @@ namespace ts { for (const u of unionTypes) { if (!containsType(u.types, type)) { const primitive = type.flags & TypeFlags.StringLiteral ? stringType : - type.flags & TypeFlags.NumberLiteral ? numberType : + type.flags & (TypeFlags.Enum | TypeFlags.NumberLiteral) ? numberType : type.flags & TypeFlags.BigIntLiteral ? bigintType : type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : undefined; @@ -15347,10 +15367,6 @@ namespace ts { return false; } - function eachIsUnionContaining(types: Type[], flag: TypeFlags) { - return every(types, t => !!(t.flags & TypeFlags.Union) && some((t as UnionType).types, tt => !!(tt.flags & flag))); - } - function removeFromEach(types: Type[], flag: TypeFlags) { for (let i = 0; i < types.length; i++) { types[i] = filterType(types[i], t => !(t.flags & flag)); @@ -15482,12 +15498,12 @@ namespace ts { // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, TypeFlags.Undefined)) { + else if (every(typeSet, t => !!(t.flags & TypeFlags.Union && (t as UnionType).types[0].flags & TypeFlags.Undefined))) { const undefinedOrMissingType = exactOptionalPropertyTypes && some(typeSet, t => containsType((t as UnionType).types, missingType)) ? missingType : undefinedType; removeFromEach(typeSet, TypeFlags.Undefined); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } - else if (eachIsUnionContaining(typeSet, TypeFlags.Null)) { + else if (every(typeSet, t => !!(t.flags & TypeFlags.Union && ((t as UnionType).types[0].flags & TypeFlags.Null || (t as UnionType).types[1].flags & TypeFlags.Null)))) { removeFromEach(typeSet, TypeFlags.Null); result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } @@ -19527,6 +19543,21 @@ namespace ts { if (containsType(targetTypes, source)) { return Ternary.True; } + if (getObjectFlags(target) & ObjectFlags.PrimitiveUnion && !(source.flags & TypeFlags.EnumLiteral) && ( + source.flags & (TypeFlags.StringLiteral | TypeFlags.BooleanLiteral | TypeFlags.BigIntLiteral) || + (relation === subtypeRelation || relation === strictSubtypeRelation) && source.flags & TypeFlags.NumberLiteral)) { + // When relating a literal type to a union of primitive types, we know the relation is false unless + // the union contains the base primitive type or the literal type in one of its fresh/regular forms. + // We exclude numeric literals for non-subtype relations because numeric literals are assignable to + // numeric enum literals with the same value. Similarly, we exclude enum literal types because + // identically named enum types are related (see isEmumTypeRelatedTo). + const alternateForm = source === (source as StringLiteralType).regularType ? (source as StringLiteralType).freshType : (source as StringLiteralType).regularType; + const primitive = source.flags & TypeFlags.StringLiteral ? stringType : + source.flags & TypeFlags.NumberLiteral ? numberType : + source.flags & TypeFlags.BigIntLiteral ? bigintType : + undefined; + return primitive && containsType(targetTypes, primitive) || alternateForm && containsType(targetTypes, alternateForm) ? Ternary.True : Ternary.False; + } const match = getMatchingUnionConstituentForType(target as UnionType, source); if (match) { const related = isRelatedTo(source, match, RecursionFlags.Target, /*reportErrors*/ false); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e4c0c0fcbbea714d86e828988a68eacca442bc7b..0580988630d23faa6233d1e260f3d506c139710c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -917,6 +917,18 @@ namespace ts { Emit, } + /** @internal */ + export const createPrinterWithDefaults = memoize(() => createPrinter({})); + + /** @internal */ + export const createPrinterWithRemoveComments = memoize(() => createPrinter({ removeComments: true })); + + /** @internal */ + export const createPrinterWithRemoveCommentsNeverAsciiEscape = memoize(() => createPrinter({ removeComments: true, neverAsciiEscape: true })); + + /** @internal */ + export const createPrinterWithRemoveCommentsOmitTrailingSemicolon = memoize(() => createPrinter({ removeComments: true, omitTrailingSemicolon: true })); + export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}): Printer { const { hasGlobalName, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 79b63a7aa70367275dc05d5891e8d94405c6d70f..b6480a80fe16a9b5206d47e0cf541199de1aaa35 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4984,6 +4984,7 @@ namespace ts { getConstEnumRelate?(): ESMap>; clearConstEnumRelate?(): void; deleteConstEnumRelate?(path: string): void; + clearQualifiedNameCache?(): void; } /* @internal */ @@ -5805,7 +5806,7 @@ namespace ts { /* @internal */ IncludesInstantiable = Substitution, /* @internal */ - NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | Object | Intersection | IncludesInstantiable, + NotPrimitiveUnion = Any | Unknown | Void | Never | Object | Intersection | IncludesInstantiable, } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; diff --git a/src/linter/ArkTSLinter_1_0/LinterRunner.ts b/src/linter/ArkTSLinter_1_0/LinterRunner.ts index d17dc70555e579052c8e31415a53b3539d6ebbd6..3e1405286c46cbf9ae1bec21ff047d4585df6949 100644 --- a/src/linter/ArkTSLinter_1_0/LinterRunner.ts +++ b/src/linter/ArkTSLinter_1_0/LinterRunner.ts @@ -106,6 +106,7 @@ export function runArkTSLinter(tsBuilderProgram: BuilderProgram, srcFile?: Sourc // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences(): void { + TypeScriptLinter.clearQualifiedNameCache(); TypeScriptLinter.clearTsTypeChecker(); Utils.clearTypeChecker(); Utils.clearTrueSymbolAtLocationCache(); diff --git a/src/linter/ArkTSLinter_1_0/TypeScriptLinter.ts b/src/linter/ArkTSLinter_1_0/TypeScriptLinter.ts index 6a04ffdbeb2b22c89ea905a4afb99cfac2a22e09..cab1536ed410bd397269b6b83e5932e05f212396 100644 --- a/src/linter/ArkTSLinter_1_0/TypeScriptLinter.ts +++ b/src/linter/ArkTSLinter_1_0/TypeScriptLinter.ts @@ -159,6 +159,12 @@ export class TypeScriptLinter { TypeScriptLinter.tsTypeChecker = {} as TypeChecker; } + public static clearQualifiedNameCache(): void { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + } + readonly handlersMap = new Map([ [SyntaxKind.ObjectLiteralExpression, this.handleObjectLiteralExpression], [SyntaxKind.ArrayLiteralExpression, this.handleArrayLiteralExpression], diff --git a/src/linter/ArkTSLinter_1_1/LinterRunner.ts b/src/linter/ArkTSLinter_1_1/LinterRunner.ts index 44b7f45bef5b2ccf764ebe0542101fb4c42010a3..f25ac8dcb2e528cf8ee8a04c8b9847c01e9835b9 100644 --- a/src/linter/ArkTSLinter_1_1/LinterRunner.ts +++ b/src/linter/ArkTSLinter_1_1/LinterRunner.ts @@ -144,6 +144,7 @@ export function runArkTSLinter(tsBuilderProgram: BuilderProgram, srcFile?: Sourc // reclaiming memory for Hvigor with "no-parallel" and "daemon", . function releaseReferences(): void { + TypeScriptLinter.clearQualifiedNameCache(); TypeScriptLinter.clearTsTypeChecker(); InteropTypescriptLinter.clearTsTypeChecker(); Utils.clearTypeChecker(); diff --git a/src/linter/ArkTSLinter_1_1/TypeScriptLinter.ts b/src/linter/ArkTSLinter_1_1/TypeScriptLinter.ts index 1aad039431a4e50981cc9971b44b345d4da15070..aa19f0b4c8ff119a1a89bf6a9e8dbb72c13e1ac5 100644 --- a/src/linter/ArkTSLinter_1_1/TypeScriptLinter.ts +++ b/src/linter/ArkTSLinter_1_1/TypeScriptLinter.ts @@ -163,6 +163,12 @@ export class TypeScriptLinter { TypeScriptLinter.tsTypeChecker = {} as TypeChecker; } + public static clearQualifiedNameCache(): void { + if (TypeScriptLinter.tsTypeChecker) { + TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache && TypeScriptLinter.tsTypeChecker.clearQualifiedNameCache(); + } + } + readonly handlersMap = new Map([ [SyntaxKind.ObjectLiteralExpression, {handler: this.handleObjectLiteralExpression, name: 'handleObjectLiteralExpression'}], [SyntaxKind.ArrayLiteralExpression, {handler: this.handleArrayLiteralExpression, name: 'handleArrayLiteralExpression'}], diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index 705613ed53a3fb06bad8052e8b206859b9f8ab5a..3d033004a04b34e893ad4855c16d920b37781ef2 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -137,7 +137,7 @@ namespace ts.CallHierarchy { } if (text === undefined) { // get the text from printing the node on a single line without comments... - const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + const printer = createPrinterWithRemoveCommentsOmitTrailingSemicolon(); text = usingSingleLineStringWriter(writer => printer.writeNode(EmitHint.Unspecified, node, node.getSourceFile(), writer)); } return { text, pos: declName.getStart(), end: declName.getEnd() }; diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 7462a2c6f2c7cfb3b7d30aacc4ebb9b9551f4332..de2e8baad40a723a4df913ca0796d6b6ed91b7d3 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -313,8 +313,7 @@ namespace ts.InlayHints { function printTypeInSingleLine(type: Type) { const flags = NodeBuilderFlags.IgnoreErrors | TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; - const options: PrinterOptions = { removeComments: true }; - const printer = createPrinter(options); + const printer = createPrinterWithRemoveComments(); return usingSingleLineStringWriter(writer => { const typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags, writer); diff --git a/src/services/services.ts b/src/services/services.ts index b76fc55cceb6b517a596326c890fa0bcb95e17f8..b85f64b76412ca9bd25ef002b7c1c8a824889496 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1392,6 +1392,9 @@ namespace ts { PerformanceDotting.start("isProgramUptoDate"); if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), fileName => compilerHost!.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { PerformanceDotting.stop("isProgramUptoDate"); + // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches; + // clear these caches to avoid affecting future compilations. + host.clearFileCache && host.clearFileCache(); return; } PerformanceDotting.stop("isProgramUptoDate"); @@ -1441,6 +1444,7 @@ namespace ts { // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); + host.clearFileCache && host.clearFileCache(); return; function getParsedCommandLine(fileName: string): ParsedCommandLine | undefined { diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 569ec1a67781371e4662773c4dc48ebaa0a77f59..cc085f0c140b8bd6665cfc60e785b7e0a431c7ff 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -572,7 +572,7 @@ namespace ts.SignatureHelp { function getTypeHelpItem(symbol: Symbol, typeParameters: readonly TypeParameter[], checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem { const typeSymbolDisplay = symbolToDisplayParts(checker, symbol); - const printer = createPrinter({ removeComments: true }); + const printer = createPrinterWithRemoveComments(); const parameters = typeParameters.map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer)); const documentation = symbol.getDocumentationComment(checker); @@ -612,7 +612,7 @@ namespace ts.SignatureHelp { function itemInfoForTypeParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo[] { const typeParameters = (candidateSignature.target || candidateSignature).typeParameters; - const printer = createPrinter({ removeComments: true }); + const printer = createPrinterWithRemoveComments(); const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer)); const thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : []; @@ -626,7 +626,7 @@ namespace ts.SignatureHelp { } function itemInfoForParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo[] { - const printer = createPrinter({ removeComments: true }); + const printer = createPrinterWithRemoveComments(); const typeParameterParts = mapToDisplayParts(writer => { if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { const args = factory.createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)); diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 6f66fb7c4e393bae8adf6ceb51fce645d7aa550f..5376e8af2386f6c9e8058d46852771bd1c99d3a4 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -146,7 +146,6 @@ namespace ts.SymbolDisplay { let hasAddedSymbolInfo = false; const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isInExpressionContext(location) || isThisInTypeQuery(location); let type: Type | undefined; - let printer: Printer; let documentationFromAlias: SymbolDisplayPart[] | undefined; let tagsFromAlias: JSDocTagInfo[] | undefined; let hasMultipleSignatures = false; @@ -621,10 +620,7 @@ namespace ts.SymbolDisplay { return { displayParts, documentation, symbolKind, tags: tags.length === 0 ? undefined : tags }; function getPrinter() { - if (!printer) { - printer = createPrinter({ removeComments: true }); - } - return printer; + return createPrinterWithRemoveComments(); } function prefixNextMeaning() { diff --git a/src/services/types.ts b/src/services/types.ts index 86c25b1b82b77e880bd9b81b24c2459eb931cc2c..963f1ba3f6716ef1204b1cd06f3cd23ec7deaa7d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -329,6 +329,7 @@ namespace ts { shouldCompletionSortCustom?: boolean; uiProps?: string[]; clearProps?(): void; + clearFileCache?(): void; } /* @internal */ diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 66516416dbd18bebc57a2c1b7a6341af233ca9db..94244dcb9e43105695e477e41579018f389df872 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2471,7 +2471,7 @@ namespace ts { export function nodeToDisplayParts(node: Node, enclosingDeclaration: Node): SymbolDisplayPart[] { const file = enclosingDeclaration.getSourceFile(); return mapToDisplayParts(writer => { - const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + const printer = createPrinterWithRemoveCommentsOmitTrailingSemicolon(); printer.writeNode(EmitHint.Unspecified, node, file, writer); }); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 765702bc62431c1a0b189add7ae40f69c94deee9..a07c00f2a53616b8e2c6e1de8847828bcb2d15b7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2543,6 +2543,7 @@ declare namespace ts { getConstEnumRelate?(): ESMap>; clearConstEnumRelate?(): void; deleteConstEnumRelate?(path: string): void; + clearQualifiedNameCache?(): void; } export enum NodeBuilderFlags { None = 0, @@ -6378,6 +6379,7 @@ declare namespace ts { shouldCompletionSortCustom?: boolean; uiProps?: string[]; clearProps?(): void; + clearFileCache?(): void; } type WithMetadata = T & { metadata?: unknown; @@ -13014,6 +13016,7 @@ declare namespace ts { skipArkTSStaticBlocksCheck: boolean; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void>; incrementCounters(node: Node | CommentRange, faultId: number, autofixable?: boolean, autofix?: Autofix[]): void; visitTSNode(node: Node): void; @@ -13632,6 +13635,7 @@ declare namespace ts { private compatibleSdkVersion; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void; name: string; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 174833fb51ac267d2b6fc405ee56498bb5a85c7a..ce41ad5ba41198b49643f2bf0ad9c9e7e9e27403 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2543,6 +2543,7 @@ declare namespace ts { getConstEnumRelate?(): ESMap>; clearConstEnumRelate?(): void; deleteConstEnumRelate?(path: string): void; + clearQualifiedNameCache?(): void; } export enum NodeBuilderFlags { None = 0, @@ -6378,6 +6379,7 @@ declare namespace ts { shouldCompletionSortCustom?: boolean; uiProps?: string[]; clearProps?(): void; + clearFileCache?(): void; } type WithMetadata = T & { metadata?: unknown; @@ -9068,6 +9070,7 @@ declare namespace ts { skipArkTSStaticBlocksCheck: boolean; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void>; incrementCounters(node: Node | CommentRange, faultId: number, autofixable?: boolean, autofix?: Autofix[]): void; visitTSNode(node: Node): void; @@ -9686,6 +9689,7 @@ declare namespace ts { private compatibleSdkVersion; constructor(sourceFile: SourceFile, tsProgram: Program, tscStrictDiagnostics?: Map | undefined); static clearTsTypeChecker(): void; + static clearQualifiedNameCache(): void; readonly handlersMap: ESMap void; name: string;