diff --git a/cli/build.rs b/cli/build.rs index 3b4bfa8a82..b41921fece 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -453,7 +453,7 @@ fn main() { ); let ts_version = ts::version(); - debug_assert_eq!(ts_version, "5.4.3"); // bump this assertion when it changes + debug_assert_eq!(ts_version, "5.4.5"); // bump this assertion when it changes println!("cargo:rustc-env=TS_VERSION={}", ts_version); println!("cargo:rerun-if-env-changed=TS_VERSION"); diff --git a/cli/tsc/00_typescript.js b/cli/tsc/00_typescript.js index a9ad0713b7..6a936223ff 100644 --- a/cli/tsc/00_typescript.js +++ b/cli/tsc/00_typescript.js @@ -35,7 +35,7 @@ var ts = (() => { "src/compiler/corePublic.ts"() { "use strict"; versionMajorMinor = "5.4"; - version = "5.4.3"; + version = "5.4.5"; Comparison = /* @__PURE__ */ ((Comparison3) => { Comparison3[Comparison3["LessThan"] = -1] = "LessThan"; Comparison3[Comparison3["EqualTo"] = 0] = "EqualTo"; @@ -5423,14 +5423,17 @@ ${lanes.join("\n")} pollingIntervalQueue(pollingInterval).pollScheduled = host.setTimeout(pollingInterval === 250 /* Low */ ? pollLowPollingIntervalQueue : pollPollingIntervalQueue, pollingInterval, pollingInterval === 250 /* Low */ ? "pollLowPollingIntervalQueue" : "pollPollingIntervalQueue", pollingIntervalQueue(pollingInterval)); } } - function createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames2) { + function createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames2, getModifiedTime3, fsWatchWithTimestamp) { const fileWatcherCallbacks = createMultiMap(); + const fileTimestamps = fsWatchWithTimestamp ? /* @__PURE__ */ new Map() : void 0; const dirWatchers = /* @__PURE__ */ new Map(); const toCanonicalName = createGetCanonicalFileName(useCaseSensitiveFileNames2); return nonPollingWatchFile; function nonPollingWatchFile(fileName, callback, _pollingInterval, fallbackOptions) { const filePath = toCanonicalName(fileName); - fileWatcherCallbacks.add(filePath, callback); + if (fileWatcherCallbacks.add(filePath, callback).length === 1 && fileTimestamps) { + fileTimestamps.set(filePath, getModifiedTime3(fileName) || missingFileModifiedTime); + } const dirPath = getDirectoryPath(filePath) || "."; const watcher = dirWatchers.get(dirPath) || createDirectoryWatcher(getDirectoryPath(fileName) || ".", dirPath, fallbackOptions); watcher.referenceCount++; @@ -5450,14 +5453,31 @@ ${lanes.join("\n")} const watcher = fsWatch( dirName, 1 /* Directory */, - (_eventName, relativeFileName, modifiedTime) => { + (eventName, relativeFileName) => { if (!isString(relativeFileName)) return; const fileName = getNormalizedAbsolutePath(relativeFileName, dirName); - const callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName)); + const filePath = toCanonicalName(fileName); + const callbacks = fileName && fileWatcherCallbacks.get(filePath); if (callbacks) { + let currentModifiedTime; + let eventKind = 1 /* Changed */; + if (fileTimestamps) { + const existingTime = fileTimestamps.get(filePath); + if (eventName === "change") { + currentModifiedTime = getModifiedTime3(fileName) || missingFileModifiedTime; + if (currentModifiedTime.getTime() === existingTime.getTime()) + return; + } + currentModifiedTime || (currentModifiedTime = getModifiedTime3(fileName) || missingFileModifiedTime); + fileTimestamps.set(filePath, currentModifiedTime); + if (existingTime === missingFileModifiedTime) + eventKind = 0 /* Created */; + else if (currentModifiedTime === missingFileModifiedTime) + eventKind = 2 /* Deleted */; + } for (const fileCallback of callbacks) { - fileCallback(fileName, 1 /* Changed */, modifiedTime); + fileCallback(fileName, eventKind, currentModifiedTime); } } }, @@ -5849,7 +5869,7 @@ ${lanes.join("\n")} ); case 5 /* UseFsEventsOnParentDirectory */: if (!nonPollingWatchFile) { - nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames2); + nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames2, getModifiedTime3, fsWatchWithTimestamp); } return nonPollingWatchFile(fileName, callback, pollingInterval, getFallbackOptions(options)); default: @@ -6024,7 +6044,7 @@ ${lanes.join("\n")} return watchPresentFileSystemEntryWithFsWatchFile(); } try { - const presentWatcher = (!fsWatchWithTimestamp ? fsWatchWorker : fsWatchWorkerHandlingTimestamp)( + const presentWatcher = (entryKind === 1 /* Directory */ || !fsWatchWithTimestamp ? fsWatchWorker : fsWatchWorkerHandlingTimestamp)( fileOrDirectory, recursive, inodeWatching ? callbackChangingToMissingFileSystemEntry : callback @@ -45457,13 +45477,21 @@ ${lanes.join("\n")} } const nearestTargetPackageJson = getNearestAncestorDirectoryWithPackageJson(host, getDirectoryPath(modulePath)); const nearestSourcePackageJson = getNearestAncestorDirectoryWithPackageJson(host, sourceDirectory); - if (nearestSourcePackageJson !== nearestTargetPackageJson) { + const ignoreCase = !hostUsesCaseSensitiveFileNames(host); + if (!packageJsonPathsAreEqual(nearestTargetPackageJson, nearestSourcePackageJson, ignoreCase)) { return maybeNonRelative; } return relativePath; } return isPathRelativeToParent(maybeNonRelative) || countPathComponents(relativePath) < countPathComponents(maybeNonRelative) ? relativePath : maybeNonRelative; } + function packageJsonPathsAreEqual(a, b, ignoreCase) { + if (a === b) + return true; + if (a === void 0 || b === void 0) + return false; + return comparePaths(a, b, ignoreCase) === 0 /* EqualTo */; + } function countPathComponents(path) { let count = 0; for (let i = startsWith(path, "./") ? 2 : 0; i < path.length; i++) { @@ -50555,15 +50583,19 @@ ${lanes.join("\n")} return true; } } - function isEntityNameVisible(entityName, enclosingDeclaration) { + function getMeaningOfEntityNameReference(entityName) { let meaning; if (entityName.parent.kind === 186 /* TypeQuery */ || entityName.parent.kind === 233 /* ExpressionWithTypeArguments */ && !isPartOfTypeNode(entityName.parent) || entityName.parent.kind === 167 /* ComputedPropertyName */) { meaning = 111551 /* Value */ | 1048576 /* ExportValue */; - } else if (entityName.kind === 166 /* QualifiedName */ || entityName.kind === 211 /* PropertyAccessExpression */ || entityName.parent.kind === 271 /* ImportEqualsDeclaration */) { + } else if (entityName.kind === 166 /* QualifiedName */ || entityName.kind === 211 /* PropertyAccessExpression */ || entityName.parent.kind === 271 /* ImportEqualsDeclaration */ || entityName.parent.kind === 166 /* QualifiedName */ && entityName.parent.left === entityName || entityName.parent.kind === 211 /* PropertyAccessExpression */ && entityName.parent.expression === entityName || entityName.parent.kind === 212 /* ElementAccessExpression */ && entityName.parent.expression === entityName) { meaning = 1920 /* Namespace */; } else { meaning = 788968 /* Type */; } + return meaning; + } + function isEntityNameVisible(entityName, enclosingDeclaration) { + const meaning = getMeaningOfEntityNameReference(entityName); const firstIdentifier = getFirstIdentifier(entityName); const symbol = resolveName( enclosingDeclaration, @@ -52624,9 +52656,10 @@ ${lanes.join("\n")} introducesError = true; return { introducesError, node }; } + const meaning = getMeaningOfEntityNameReference(node); const sym = resolveEntityName( leftmost, - -1 /* All */, + meaning, /*ignoreErrors*/ true, /*dontResolveAlias*/ @@ -52636,13 +52669,13 @@ ${lanes.join("\n")} if (isSymbolAccessible( sym, context.enclosingDeclaration, - -1 /* All */, + meaning, /*shouldComputeAliasesToMakeVisible*/ false ).accessibility !== 0 /* Accessible */) { introducesError = true; } else { - context.tracker.trackSymbol(sym, context.enclosingDeclaration, -1 /* All */); + context.tracker.trackSymbol(sym, context.enclosingDeclaration, meaning); includePrivateSymbol == null ? void 0 : includePrivateSymbol(sym); } if (isIdentifier(node)) { @@ -57870,12 +57903,10 @@ ${lanes.join("\n")} const target = type.target ?? type; const typeVariable = getHomomorphicTypeVariable(target); if (typeVariable && !target.declaration.nameType) { - const constraint = getConstraintTypeFromMappedType(type); - if (constraint.flags & 4194304 /* Index */) { - const baseConstraint = getBaseConstraintOfType(constraint.type); - if (baseConstraint && everyType(baseConstraint, (t) => isArrayOrTupleType(t) || isArrayOrTupleOrIntersection(t))) { - return instantiateType(target, prependTypeMapping(typeVariable, baseConstraint, type.mapper)); - } + const modifiersType = getModifiersTypeFromMappedType(type); + const baseConstraint = isGenericMappedType(modifiersType) ? getApparentTypeOfMappedType(modifiersType) : getBaseConstraintOfType(modifiersType); + if (baseConstraint && everyType(baseConstraint, (t) => isArrayOrTupleType(t) || isArrayOrTupleOrIntersection(t))) { + return instantiateType(target, prependTypeMapping(typeVariable, baseConstraint, type.mapper)); } } return type; @@ -58036,13 +58067,13 @@ ${lanes.join("\n")} } function getUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment) { var _a, _b, _c; - let property = ((_a = type.propertyCacheWithoutObjectFunctionPropertyAugment) == null ? void 0 : _a.get(name)) || !skipObjectFunctionPropertyAugment ? (_b = type.propertyCache) == null ? void 0 : _b.get(name) : void 0; + let property = skipObjectFunctionPropertyAugment ? (_a = type.propertyCacheWithoutObjectFunctionPropertyAugment) == null ? void 0 : _a.get(name) : (_b = type.propertyCache) == null ? void 0 : _b.get(name); if (!property) { property = createUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment); if (property) { const properties = skipObjectFunctionPropertyAugment ? type.propertyCacheWithoutObjectFunctionPropertyAugment || (type.propertyCacheWithoutObjectFunctionPropertyAugment = createSymbolTable()) : type.propertyCache || (type.propertyCache = createSymbolTable()); properties.set(name, property); - if (skipObjectFunctionPropertyAugment && !((_c = type.propertyCache) == null ? void 0 : _c.get(name))) { + if (skipObjectFunctionPropertyAugment && !(getCheckFlags(property) & 48 /* Partial */) && !((_c = type.propertyCache) == null ? void 0 : _c.get(name))) { const properties2 = type.propertyCache || (type.propertyCache = createSymbolTable()); properties2.set(name, property); } @@ -60549,6 +60580,9 @@ ${lanes.join("\n")} } else if (every(typeSet, (t) => !!(t.flags & 1048576 /* Union */ && (t.types[0].flags & 65536 /* Null */ || t.types[1].flags & 65536 /* Null */)))) { removeFromEach(typeSet, 65536 /* Null */); result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* Literal */, aliasSymbol, aliasTypeArguments); + } else if (typeSet.length >= 4) { + const middle = Math.floor(typeSet.length / 2); + result = getIntersectionType([getIntersectionType(typeSet.slice(0, middle)), getIntersectionType(typeSet.slice(middle))], aliasSymbol, aliasTypeArguments); } else { if (!checkCrossProductUnion(typeSet)) { return errorType; @@ -150636,7 +150670,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")} break; case 3 /* CommonJS */: case 2 /* Namespace */: - Debug.assert(entry.namespaceLikeImport === void 0 || entry.namespaceLikeImport.name === symbolName2, "Namespacelike import should be missing or match symbolName"); + Debug.assert(entry.namespaceLikeImport === void 0 || entry.namespaceLikeImport.name === symbolName2, "Namespacelike import shoudl be missing or match symbolName"); entry.namespaceLikeImport = { importKind, name: symbolName2, addAsTypeOnly }; break; } @@ -159903,7 +159937,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")} } function symbolAppearsToBeTypeOnly(symbol) { var _a; - return !(symbol.flags & 111551 /* Value */) && (!isInJSFile((_a = symbol.declarations) == null ? void 0 : _a[0]) || !!(symbol.flags & 788968 /* Type */)); + const flags = getCombinedLocalAndExportSymbolFlags(skipAlias(symbol, typeChecker)); + return !(flags & 111551 /* Value */) && (!isInJSFile((_a = symbol.declarations) == null ? void 0 : _a[0]) || !!(flags & 788968 /* Type */)); } } function getLabelCompletionAtPosition(node) { @@ -160199,10 +160234,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")} return isJsxExpression(parent2) && !isJsxElement(parent2.parent) && !isJsxFragment(parent2.parent) ? checker.getContextualTypeForJsxAttribute(parent2.parent) : void 0; default: const argInfo = ts_SignatureHelp_exports.getArgumentInfoForCompletions(previousToken, position, sourceFile, checker); - return argInfo ? ( - // At `,`, treat this as the next argument after the comma. - checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (previousToken.kind === 28 /* CommaToken */ ? 1 : 0)) - ) : isEqualityOperatorKind(previousToken.kind) && isBinaryExpression(parent2) && isEqualityOperatorKind(parent2.operatorToken.kind) ? ( + return argInfo ? checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex) : isEqualityOperatorKind(previousToken.kind) && isBinaryExpression(parent2) && isEqualityOperatorKind(parent2.operatorToken.kind) ? ( // completion at `x ===/**/` should be for the right side checker.getTypeAtLocation(parent2.left) ) : checker.getContextualType(previousToken, 4 /* Completions */) || checker.getContextualType(previousToken); @@ -168766,12 +168798,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")} if (!info) return void 0; const { list, argumentIndex } = info; - const argumentCount = getArgumentCount( - list, - /*ignoreTrailingComma*/ - isInString(sourceFile, position, node), - checker - ); + const argumentCount = getArgumentCount(checker, list); if (argumentIndex !== 0) { Debug.assertLessThan(argumentIndex, argumentCount); } @@ -168783,7 +168810,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")} return { list: getChildListThatStartsWithOpenerToken(node.parent, node, sourceFile), argumentIndex: 0 }; } else { const list = findContainingList(node); - return list && { list, argumentIndex: getArgumentIndex(list, node, checker) }; + return list && { list, argumentIndex: getArgumentIndex(checker, list, node) }; } } function getImmediatelyContainingArgumentInfo(node, position, sourceFile, checker) { @@ -168913,24 +168940,6 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")} return isFunctionTypeNode(d) ? (_a = tryCast(d.parent, canHaveSymbol)) == null ? void 0 : _a.symbol : void 0; }) || s : s; } - function getArgumentIndex(argumentsList, node, checker) { - const args = argumentsList.getChildren(); - let argumentIndex = 0; - for (let pos = 0; pos < length(args); pos++) { - const child = args[pos]; - if (child === node) { - break; - } - if (isSpreadElement(child)) { - argumentIndex = argumentIndex + getSpreadElementCount(child, checker) + (pos > 0 ? pos : 0); - } else { - if (child.kind !== 28 /* CommaToken */) { - argumentIndex++; - } - } - } - return argumentIndex; - } function getSpreadElementCount(node, checker) { const spreadType = checker.getTypeAtLocation(node.expression); if (checker.isTupleType(spreadType)) { @@ -168943,19 +168952,48 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")} } return 0; } - function getArgumentCount(argumentsList, ignoreTrailingComma, checker) { - const listChildren = argumentsList.getChildren(); - let argumentCount = 0; - for (const child of listChildren) { - if (isSpreadElement(child)) { - argumentCount = argumentCount + getSpreadElementCount(child, checker); + function getArgumentIndex(checker, argumentsList, node) { + return getArgumentIndexOrCount(checker, argumentsList, node); + } + function getArgumentCount(checker, argumentsList) { + return getArgumentIndexOrCount( + checker, + argumentsList, + /*node*/ + void 0 + ); + } + function getArgumentIndexOrCount(checker, argumentsList, node) { + const args = argumentsList.getChildren(); + let argumentIndex = 0; + let skipComma = false; + for (const child of args) { + if (node && child === node) { + if (!skipComma && child.kind === 28 /* CommaToken */) { + argumentIndex++; + } + return argumentIndex; } + if (isSpreadElement(child)) { + argumentIndex += getSpreadElementCount(child, checker); + skipComma = true; + continue; + } + if (child.kind !== 28 /* CommaToken */) { + argumentIndex++; + skipComma = true; + continue; + } + if (skipComma) { + skipComma = false; + continue; + } + argumentIndex++; } - argumentCount = argumentCount + countWhere(listChildren, (arg) => arg.kind !== 28 /* CommaToken */); - if (!ignoreTrailingComma && listChildren.length > 0 && last(listChildren).kind === 28 /* CommaToken */) { - argumentCount++; + if (node) { + return argumentIndex; } - return argumentCount; + return args.length && last(args).kind === 28 /* CommaToken */ ? argumentIndex + 1 : argumentIndex; } function getArgumentIndexForTemplatePiece(spanIndex, node, position, sourceFile) { Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node."); @@ -178543,7 +178581,16 @@ ${options.prefix}` : "\n" : options.prefix recursive ? watchedDirectoriesRecursive : watchedDirectories, path, callback, - (id) => ({ eventName: CreateDirectoryWatcherEvent, data: { id, path, recursive: !!recursive } }) + (id) => ({ + eventName: CreateDirectoryWatcherEvent, + data: { + id, + path, + recursive: !!recursive, + // Special case node_modules as we watch it for changes to closed script infos as well + ignoreUpdate: !path.endsWith("/node_modules") ? true : void 0 + } + }) ); } function getOrCreateFileWatcher({ pathToId, idToCallbacks }, path, callback, event) { @@ -178570,24 +178617,28 @@ ${options.prefix}` : "\n" : options.prefix } }; } - function onWatchChange({ id, path, eventType }) { - onFileWatcherCallback(id, path, eventType); - onDirectoryWatcherCallback(watchedDirectories, id, path, eventType); - onDirectoryWatcherCallback(watchedDirectoriesRecursive, id, path, eventType); + function onWatchChange(args) { + if (isArray(args)) + args.forEach(onWatchChangeRequestArgs); + else + onWatchChangeRequestArgs(args); } - function onFileWatcherCallback(id, eventPath, eventType) { - var _a; - (_a = watchedFiles.idToCallbacks.get(id)) == null ? void 0 : _a.forEach((callback) => { - const eventKind = eventType === "create" ? 0 /* Created */ : eventType === "delete" ? 2 /* Deleted */ : 1 /* Changed */; - callback(eventPath, eventKind); - }); + function onWatchChangeRequestArgs({ id, created, deleted, updated }) { + onWatchEventType(id, created, 0 /* Created */); + onWatchEventType(id, deleted, 2 /* Deleted */); + onWatchEventType(id, updated, 1 /* Changed */); } - function onDirectoryWatcherCallback({ idToCallbacks }, id, eventPath, eventType) { - var _a; - if (eventType === "update") + function onWatchEventType(id, paths, eventKind) { + if (!(paths == null ? void 0 : paths.length)) return; - (_a = idToCallbacks.get(id)) == null ? void 0 : _a.forEach((callback) => { - callback(eventPath); + forEachCallback(watchedFiles, id, paths, (callback, eventPath) => callback(eventPath, eventKind)); + forEachCallback(watchedDirectories, id, paths, (callback, eventPath) => callback(eventPath)); + forEachCallback(watchedDirectoriesRecursive, id, paths, (callback, eventPath) => callback(eventPath)); + } + function forEachCallback(hostWatcherMap, id, eventPaths, cb) { + var _a; + (_a = hostWatcherMap.idToCallbacks.get(id)) == null ? void 0 : _a.forEach((callback) => { + eventPaths.forEach((eventPath) => cb(callback, normalizeSlashes(eventPath))); }); } } diff --git a/cli/tsc/dts/lib.dom.d.ts b/cli/tsc/dts/lib.dom.d.ts index da7364f2a9..fab313d112 100644 --- a/cli/tsc/dts/lib.dom.d.ts +++ b/cli/tsc/dts/lib.dom.d.ts @@ -25582,7 +25582,7 @@ interface WebSocket extends EventTarget { */ readonly url: string; /** - * Closes the WebSocket connection, optionally using code as the WebSocket connection close code and reason as the WebSocket connection close reason. + * Closes the WebSocket connection, optionally using code as the the WebSocket connection close code and reason as the the WebSocket connection close reason. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/close) */ diff --git a/cli/tsc/dts/lib.webworker.d.ts b/cli/tsc/dts/lib.webworker.d.ts index 0cc7df77d3..8fd57617a9 100644 --- a/cli/tsc/dts/lib.webworker.d.ts +++ b/cli/tsc/dts/lib.webworker.d.ts @@ -8292,7 +8292,7 @@ interface WebSocket extends EventTarget { */ readonly url: string; /** - * Closes the WebSocket connection, optionally using code as the WebSocket connection close code and reason as the WebSocket connection close reason. + * Closes the WebSocket connection, optionally using code as the the WebSocket connection close code and reason as the the WebSocket connection close reason. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/close) */ diff --git a/cli/tsc/dts/typescript.d.ts b/cli/tsc/dts/typescript.d.ts index 206b524075..3cf955e29f 100644 --- a/cli/tsc/dts/typescript.d.ts +++ b/cli/tsc/dts/typescript.d.ts @@ -1510,12 +1510,13 @@ declare namespace ts { } interface WatchChangeRequest extends Request { command: CommandTypes.WatchChange; - arguments: WatchChangeRequestArgs; + arguments: WatchChangeRequestArgs | readonly WatchChangeRequestArgs[]; } interface WatchChangeRequestArgs { id: number; - path: string; - eventType: "create" | "delete" | "update"; + created?: string[]; + deleted?: string[]; + updated?: string[]; } /** * Request to obtain the list of files that should be regenerated if target file is recompiled. @@ -2452,6 +2453,7 @@ declare namespace ts { readonly id: number; readonly path: string; readonly recursive: boolean; + readonly ignoreUpdate?: boolean; } type CloseFileWatcherEventName = "closeFileWatcher"; interface CloseFileWatcherEvent extends Event { diff --git a/tests/unit/version_test.ts b/tests/unit/version_test.ts index daed9fda68..bc0297f23f 100644 --- a/tests/unit/version_test.ts +++ b/tests/unit/version_test.ts @@ -6,5 +6,5 @@ Deno.test(function version() { const pattern = /^\d+\.\d+\.\d+/; assert(pattern.test(Deno.version.deno)); assert(pattern.test(Deno.version.v8)); - assertEquals(Deno.version.typescript, "5.4.3"); + assertEquals(Deno.version.typescript, "5.4.5"); });