From b727ad8c2b613789c0d0c63ebf54dcd689969eee Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 11 Sep 2024 03:33:07 -0400 Subject: [PATCH 01/14] Re-integrate changes from 5.6.2 branch --- src/compiler/_namespaces/ts.ts | 1 + src/compiler/builderState.ts | 2 +- src/compiler/checker.ts | 240 ++++++++++++++++++++++-------- src/compiler/commandLineParser.ts | 1 + src/compiler/deno.ts | 186 +++++++++++++++++++++++ src/compiler/path.ts | 10 ++ src/compiler/types.ts | 2 +- src/compiler/utilities.ts | 12 +- src/lib/dom.generated.d.ts | 1 + src/lib/es2020.intl.d.ts | 2 +- src/lib/es5.d.ts | 2 +- src/lib/webworker.generated.d.ts | 1 + src/services/completions.ts | 3 +- 13 files changed, 395 insertions(+), 68 deletions(-) create mode 100644 src/compiler/deno.ts diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts index 94fb16857d38e..33a6a2844da88 100644 --- a/src/compiler/_namespaces/ts.ts +++ b/src/compiler/_namespaces/ts.ts @@ -10,6 +10,7 @@ export * from "../types.js"; export * from "../sys.js"; export * from "../path.js"; export * from "../diagnosticInformationMap.generated.js"; +export * as deno from "../deno.js"; export * from "../scanner.js"; export * from "../utilitiesPublic.js"; export * from "../utilities.js"; diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index cf9932e94631b..884a317a55b0b 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -260,7 +260,7 @@ export namespace BuilderState { } // From ambient modules - for (const ambientModule of program.getTypeChecker().getAmbientModules()) { + for (const ambientModule of program.getTypeChecker().getAmbientModules(sourceFile)) { if (ambientModule.declarations && ambientModule.declarations.length > 1) { addReferenceFromAmbientModule(ambientModule); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0ba770c6764e1..b0a16431a5d32 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -143,6 +143,7 @@ import { defaultMaximumTruncationLength, DeferredTypeReference, DeleteExpression, + deno, Diagnostic, DiagnosticAndArguments, DiagnosticArguments, @@ -1534,14 +1535,52 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { evaluateEntityNameExpression, }); - var globals = createSymbolTable(); + var denoGlobals = createSymbolTable(); + var nodeGlobals = createSymbolTable(); var undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined" as __String); undefinedSymbol.declarations = []; - var globalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); - globalThisSymbol.exports = globals; - globalThisSymbol.declarations = []; - globals.set(globalThisSymbol.escapedName, globalThisSymbol); + var denoGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); + denoGlobalThisSymbol.exports = denoGlobals; + denoGlobalThisSymbol.declarations = []; + denoGlobals.set(denoGlobalThisSymbol.escapedName, denoGlobalThisSymbol); + + const denoContext = deno.createDenoForkContext({ + globals: denoGlobals, + nodeGlobals, + mergeSymbol, + }); + + const nodeGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); + nodeGlobalThisSymbol.exports = denoContext.combinedGlobals; + nodeGlobalThisSymbol.declarations = []; + nodeGlobals.set(nodeGlobalThisSymbol.escapedName, nodeGlobalThisSymbol); + + // deno: huge hacks to get @types/node to work + nodeGlobals.set( + "onmessage" as __String, + createSymbol(SymbolFlags.Module, "onmessage" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "onabort" as __String, + createSymbol(SymbolFlags.Module, "onabort" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "ReportingObserver" as __String, + createSymbol(SymbolFlags.Module, "ReportingObserver" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "PerformanceObserver" as __String, + createSymbol(SymbolFlags.Module, "PerformanceObserver" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "PerformanceObserverEntryList" as __String, + createSymbol(SymbolFlags.Module, "PerformanceObserverEntryList" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "PerformanceResourceTiming" as __String, + createSymbol(SymbolFlags.Module, "PerformanceResourceTiming" as __String, CheckFlags.Readonly), + ); var argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String); var requireSymbol = createSymbol(SymbolFlags.Property, "require" as __String); @@ -1559,7 +1598,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { compilerOptions, requireSymbol, argumentsSymbol, - globals, + denoGlobals, + nodeGlobals, + denoContext, getSymbolOfDeclaration, error, getRequiresScopeChangeCache, @@ -1574,7 +1615,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { compilerOptions, requireSymbol, argumentsSymbol, - globals, + denoGlobals, + nodeGlobals, + denoContext, getSymbolOfDeclaration, error, getRequiresScopeChangeCache, @@ -2215,6 +2258,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var reverseMappedCache = new Map(); var reverseHomomorphicMappedCache = new Map(); var ambientModulesCache: Symbol[] | undefined; + var nodeAmbientModulesCache: Symbol[] | undefined; /** * List of every ambient module with a "*" wildcard. * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches. @@ -2386,7 +2430,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (!isIdentifier(node.expression.expression)) return false; // Exactly `globalThis.Symbol.something` and `globalThis` resolves to the global `globalThis` - return idText(node.expression.name) === "Symbol" && idText(node.expression.expression) === "globalThis" && getResolvedSymbol(node.expression.expression) === globalThisSymbol; + if (idText(node.expression.name) !== "Symbol" || idText(node.expression.expression) !== "globalThis") return false; + const resolvedSymbol = getResolvedSymbol(node.expression.expression); + return resolvedSymbol === denoGlobalThisSymbol || resolvedSymbol === nodeGlobalThisSymbol; } function getCachedType(key: string | undefined) { @@ -2698,7 +2744,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Do not report an error when merging `var globalThis` with the built-in `globalThis`, // as we will already report a "Declaration name conflicts..." error, and this error // won't make much sense. - if (target !== globalThisSymbol) { + if (target !== denoGlobalThisSymbol && target !== nodeGlobalThisSymbol) { error( source.declarations && getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, @@ -2814,7 +2860,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (isGlobalScopeAugmentation(moduleAugmentation)) { - mergeSymbolTable(globals, moduleAugmentation.symbol.exports!); + denoContext.mergeGlobalSymbolTable(moduleAugmentation, moduleAugmentation.symbol.exports!); } else { // find a module that about to be augmented @@ -2864,17 +2910,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function addUndefinedToGlobalsOrErrorOnRedeclaration() { const name = undefinedSymbol.escapedName; - const targetSymbol = globals.get(name); - if (targetSymbol) { - forEach(targetSymbol.declarations, declaration => { - // checkTypeNameIsReserved will have added better diagnostics for type declarations. - if (!isTypeDeclaration(declaration)) { - diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, unescapeLeadingUnderscores(name))); - } - }); - } - else { - globals.set(name, undefinedSymbol); + for (const globals of [nodeGlobals, denoGlobals]) { + const targetSymbol = globals.get(name); + if (targetSymbol) { + forEach(targetSymbol.declarations, declaration => { + // checkTypeNameIsReserved will have added better diagnostics for type declarations. + if (!isTypeDeclaration(declaration)) { + diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, unescapeLeadingUnderscores(name))); + } + }); + } + else { + globals.set(name, undefinedSymbol); + } } } @@ -3301,7 +3349,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Look at 'compilerOptions.isolatedModules' and not 'getIsolatedModules(...)' (which considers 'verbatimModuleSyntax') // here because 'verbatimModuleSyntax' will already have an error for importing a type without 'import type'. if (compilerOptions.isolatedModules && result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value) { - const isGlobal = getSymbol(globals, name, meaning) === result; + const isNodeFile = denoContext.hasNodeSourceFile(lastLocation); + const fileGlobals = isNodeFile ? nodeGlobals : denoGlobals; + const isGlobal = getSymbol(fileGlobals, name, meaning) === result; const nonValueSymbol = isGlobal && isSourceFile(lastLocation) && lastLocation.locals && getSymbol(lastLocation.locals, name, ~SymbolFlags.Value); if (nonValueSymbol) { const importDecl = nonValueSymbol.declarations?.find(d => d.kind === SyntaxKind.ImportSpecifier || d.kind === SyntaxKind.ImportClause || d.kind === SyntaxKind.NamespaceImport || d.kind === SyntaxKind.ImportEqualsDeclaration); @@ -3724,11 +3774,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // In Node.js, CommonJS modules always have a synthetic default when imported into ESM return true; } - if (usageMode === ModuleKind.ESNext && targetMode === ModuleKind.ESNext) { - // No matter what the `module` setting is, if we're confident that both files - // are ESM, there cannot be a synthetic default. - return false; - } + // deno: commented out for https://github.com/microsoft/TypeScript/issues/51321 + // if (usageMode === ModuleKind.ESNext && targetMode === ModuleKind.ESNext) { + // // No matter what the `module` setting is, if we're confident that both files + // // are ESM, there cannot be a synthetic default. + // return false; + // } } if (!allowSyntheticDefaultImports) { return false; @@ -4613,6 +4664,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function resolveExternalModule(location: Node, moduleReference: string, moduleNotFoundError: DiagnosticMessage | undefined, errorNode: Node | undefined, isForAugmentation = false): Symbol | undefined { + const result = resolveExternalModuleInner(location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation); + + // deno: attempt to resolve an npm package reference to its bare specifier w/ path ambient module + // when not found and the symbol has zero exports + if (moduleReference.startsWith("npm:") && (result === undefined || result?.exports?.size === 0)) { + const npmPackageRef = deno.tryParseNpmPackageReference(moduleReference); + if (npmPackageRef) { + const bareSpecifier = npmPackageRef.name + (npmPackageRef.subPath === undefined ? "" : "/" + npmPackageRef.subPath); + const ambientModule = tryFindAmbientModule(bareSpecifier, /*withAugmentations*/ true); + if (ambientModule) { + return ambientModule; + } + } + } + + return result; + } + + function resolveExternalModuleInner(location: Node, moduleReference: string, moduleNotFoundError: DiagnosticMessage | undefined, errorNode: Node | undefined, isForAugmentation = false): Symbol | undefined { if (errorNode && startsWith(moduleReference, "@types/")) { const diag = Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1; const withoutAtTypePrefix = removePrefix(moduleReference, "@types/"); @@ -5551,7 +5621,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - return callback(globals, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ true); + if (denoContext.hasNodeSourceFile(enclosingDeclaration)) { + result = callback(nodeGlobals, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ true); + if (result) { + return result; + } + } + + return callback(denoGlobals, /*ignoreQualification*/ undefined, /*isLocalNameLookup*/ true); } function getQualifiedLeftMeaning(rightMeaning: SymbolFlags) { @@ -5645,7 +5722,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { }); // If there's no result and we're looking at the global symbol table, treat `globalThis` like an alias and try to lookup thru that - return result || (symbols === globals ? getCandidateListForSymbol(globalThisSymbol, globalThisSymbol, ignoreQualification) : undefined); + if (result) { + return result; + } + const globalSymbol = symbols === nodeGlobals ? nodeGlobalThisSymbol : symbols === denoGlobals ? denoGlobalThisSymbol : undefined; + return globalSymbol !== undefined ? getCandidateListForSymbol(globalSymbol, globalSymbol, ignoreQualification) : undefined; } function getCandidateListForSymbol(symbolFromSymbolTable: Symbol, resolvedImportedSymbol: Symbol, ignoreQualification: boolean | undefined) { @@ -8202,14 +8283,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // An `import` type directed at an esm format file is only going to resolve in esm mode - set the esm mode assertion if (targetFile?.impliedNodeFormat === ModuleKind.ESNext && targetFile.impliedNodeFormat !== contextFile?.impliedNodeFormat) { specifier = getSpecifierForModuleSymbol(chain[0], context, ModuleKind.ESNext); - attributes = factory.createImportAttributes( - factory.createNodeArray([ - factory.createImportAttribute( - factory.createStringLiteral("resolution-mode"), - factory.createStringLiteral("import"), - ), - ]), - ); + // deno: ignored because it's too noisy and unnecessary + // attributes = factory.createImportAttributes( + // factory.createNodeArray([ + // factory.createImportAttribute( + // factory.createStringLiteral("resolution-mode"), + // factory.createStringLiteral("import"), + // ), + // ]), + // ); } } if (!specifier) { @@ -13899,7 +13981,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Combinations of function, class, enum and module let members = getExportsOfSymbol(symbol); let indexInfos: IndexInfo[] | undefined; - if (symbol === globalThisSymbol) { + if (symbol === denoGlobalThisSymbol || symbol === nodeGlobalThisSymbol) { const varsOnly = new Map<__String, Symbol>(); members.forEach(p => { if (!(p.flags & SymbolFlags.BlockScoped) && !(p.flags & SymbolFlags.ValueModule && p.declarations?.length && every(p.declarations, isAmbientModule))) { @@ -15347,7 +15429,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isExternalModuleNameRelative(moduleName)) { return undefined; } - const symbol = getSymbol(globals, '"' + moduleName + '"' as __String, SymbolFlags.ValueModule); + const symbol = getSymbol(denoContext.combinedGlobals, '"' + moduleName + '"' as __String, SymbolFlags.ValueModule); // merged symbol is module declaration symbol combined with all augmentations return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol; } @@ -18639,7 +18721,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports!.has(propName) && (globalThisSymbol.exports!.get(propName)!.flags & SymbolFlags.BlockScoped)) { + if (objectType.symbol === denoGlobalThisSymbol && propName !== undefined && denoGlobalThisSymbol.exports!.has(propName) && (denoGlobalThisSymbol.exports!.get(propName)!.flags & SymbolFlags.BlockScoped)) { + error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); + } + // deno: ensure condition and body match the above + else if (objectType.symbol === nodeGlobalThisSymbol && propName !== undefined && nodeGlobalThisSymbol.exports!.has(propName) && (nodeGlobalThisSymbol.exports!.get(propName)!.flags & SymbolFlags.BlockScoped)) { error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); } else if (noImplicitAny && !(accessFlags & AccessFlags.SuppressNoImplicitAnyError)) { @@ -29944,7 +30030,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return; // Skip for invalid syntax like this: export { "x" } } const symbol = resolveName(exportedName, exportedName.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*isUse*/ true); - if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { + if (symbol && (symbol === undefinedSymbol || symbol === denoGlobalThisSymbol || symbol === nodeGlobalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { // Do nothing, non-local symbol } else { @@ -30665,8 +30751,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const type = tryGetThisTypeAt(node, /*includeGlobalThis*/ true, container); if (noImplicitThis) { - const globalThisType = getTypeOfSymbol(globalThisSymbol); - if (type === globalThisType && capturedByArrowFunction) { + const globalThisType = getTypeOfSymbol(denoGlobalThisSymbol); + if ((type === globalThisType || type === getTypeOfSymbol(nodeGlobalThisSymbol)) && capturedByArrowFunction) { error(node, Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this); } else if (!type) { @@ -30728,7 +30814,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefinedType; } else if (includeGlobalThis) { - return getTypeOfSymbol(globalThisSymbol); + if (denoContext.hasNodeSourceFile(container)) { + return getTypeOfSymbol(nodeGlobalThisSymbol); + } + return getTypeOfSymbol(denoGlobalThisSymbol); } } } @@ -34100,8 +34189,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!isUncheckedJS && isJSLiteralType(leftType)) { return anyType; } - if (leftType.symbol === globalThisSymbol) { - if (globalThisSymbol.exports!.has(right.escapedText) && (globalThisSymbol.exports!.get(right.escapedText)!.flags & SymbolFlags.BlockScoped)) { + if (leftType.symbol === denoGlobalThisSymbol) { + if (denoGlobalThisSymbol.exports!.has(right.escapedText) && (denoGlobalThisSymbol.exports!.get(right.escapedText)!.flags & SymbolFlags.BlockScoped)) { error(right, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(right.escapedText), typeToString(leftType)); } else if (noImplicitAny) { @@ -34109,6 +34198,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return anyType; } + // deno: ensure condition matches above + if (leftType.symbol === nodeGlobalThisSymbol) { + // deno: don't bother with errors like above for simplicity + return anyType; + } if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) { reportNonexistentProperty(right, isThisTypeParameter(leftType) ? apparentType : leftType, isUncheckedJS); } @@ -34448,7 +34542,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. if (symbol) return symbol; let candidates: Symbol[]; - if (symbols === globals) { + if (symbols === denoGlobals || symbols == nodeGlobals) { const primitives = mapDefined( ["string", "number", "boolean", "object", "bigint", "symbol"], s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as __String) @@ -47802,7 +47896,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases) const symbol = resolveName(exportedName, exportedName.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*isUse*/ true); - if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { + if (symbol && (symbol === undefinedSymbol || symbol === denoGlobalThisSymbol || symbol === nodeGlobalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, idText(exportedName)); } else { @@ -48710,7 +48804,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { location = location.parent; } - copySymbols(globals, meaning); + if (denoContext.hasNodeSourceFile(location)) { + copySymbols(nodeGlobals, meaning); + } + + copySymbols(denoGlobals, meaning); } /** @@ -50096,7 +50194,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function hasGlobalName(name: string): boolean { - return globals.has(escapeLeadingUnderscores(name)); + // deno: seems ok not to bother with nodeGlobals here since + // this is just a public api function that we don't bother with + // NOTICE: Make sure to check that's still the case when upgrading!! + return denoGlobals.has(escapeLeadingUnderscores(name)); } function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { @@ -50415,10 +50516,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis")); } } - mergeSymbolTable(globals, file.locals!); + denoContext.mergeGlobalSymbolTable(file, file.locals!); } if (file.jsGlobalAugmentations) { - mergeSymbolTable(globals, file.jsGlobalAugmentations); + denoContext.mergeGlobalSymbolTable(file, file.jsGlobalAugmentations); } if (file.patternAmbientModules && file.patternAmbientModules.length) { patternAmbientModules = concatenate(patternAmbientModules, file.patternAmbientModules); @@ -50429,9 +50530,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (file.symbol && file.symbol.globalExports) { // Merge in UMD exports with first-in-wins semantics (see #9771) const source = file.symbol.globalExports; + const isNodeFile = denoContext.hasNodeSourceFile(file); source.forEach((sourceSymbol, id) => { - if (!globals.has(id)) { - globals.set(id, sourceSymbol); + const envGlobals = isNodeFile ? denoContext.getGlobalsForName(id) : denoGlobals; + if (!envGlobals.has(id)) { + envGlobals.set(id, sourceSymbol); } }); } @@ -50459,7 +50562,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { getSymbolLinks(undefinedSymbol).type = undefinedWideningType; getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as __String, /*arity*/ 0, /*reportErrors*/ true); getSymbolLinks(unknownSymbol).type = errorType; - getSymbolLinks(globalThisSymbol).type = createObjectType(ObjectFlags.Anonymous, globalThisSymbol); + getSymbolLinks(denoGlobalThisSymbol).type = createObjectType(ObjectFlags.Anonymous, denoGlobalThisSymbol); + getSymbolLinks(nodeGlobalThisSymbol).type = createObjectType(ObjectFlags.Anonymous, nodeGlobalThisSymbol); // Initialize special types globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true); @@ -52383,17 +52487,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function getAmbientModules(): Symbol[] { - if (!ambientModulesCache) { - ambientModulesCache = []; - globals.forEach((global, sym) => { + function getAmbientModules(sourceFile?: SourceFile): Symbol[] { + const isNode = denoContext.hasNodeSourceFile(sourceFile); + if (isNode) { + if (!nodeAmbientModulesCache) { + nodeAmbientModulesCache = getAmbientModules(denoContext.combinedGlobals); + } + return nodeAmbientModulesCache; + } + else { + if (!ambientModulesCache) { + ambientModulesCache = getAmbientModules(denoGlobals); + } + return ambientModulesCache; + } + + function getAmbientModules(envGlobals: SymbolTable) { + const result: Symbol[] = []; + envGlobals.forEach((global, sym) => { // No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module. if (ambientModuleSymbolRegex.test(sym as string)) { - ambientModulesCache!.push(global); + result.push(global); } }); + return result; } - return ambientModulesCache; } function checkGrammarImportClause(node: ImportClause): boolean { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index e4fb6e7a834e7..6e8a39f0f0a57 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -169,6 +169,7 @@ const libEntries: [string, string][] = [ ["dom", "lib.dom.d.ts"], ["dom.iterable", "lib.dom.iterable.d.ts"], ["dom.asynciterable", "lib.dom.asynciterable.d.ts"], + ["dom.extras", "lib.dom.extras.d.ts"], ["webworker", "lib.webworker.d.ts"], ["webworker.importscripts", "lib.webworker.importscripts.d.ts"], ["webworker.iterable", "lib.webworker.iterable.d.ts"], diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts new file mode 100644 index 0000000000000..32e938c119e7d --- /dev/null +++ b/src/compiler/deno.ts @@ -0,0 +1,186 @@ +import * as ts from "./_namespaces/ts"; + +export type IsNodeSourceFileCallback = (sourceFile: ts.SourceFile) => boolean; + +let isNodeSourceFile: IsNodeSourceFileCallback = () => false; +let nodeOnlyGlobalNames = new Set(); + +export function setIsNodeSourceFileCallback(callback: IsNodeSourceFileCallback) { + isNodeSourceFile = callback; +} + +export function setNodeOnlyGlobalNames(names: readonly string[]) { + nodeOnlyGlobalNames = new Set(names) as Set; +} + +// When upgrading: +// Inspect all usages of "globals" and "globalThisSymbol" in checker.ts +// - Beware that `globalThisType` might refer to the global `this` type +// and not the global `globalThis` type + +export interface DenoForkContext { + hasNodeSourceFile: (node: ts.Node | undefined) => boolean; + getGlobalsForName: (id: ts.__String) => ts.SymbolTable; + mergeGlobalSymbolTable: (node: ts.Node, source: ts.SymbolTable, unidirectional?: boolean) => void; + combinedGlobals: ts.SymbolTable; +} + +export function createDenoForkContext({ + mergeSymbol, + globals, + nodeGlobals, +}: { + mergeSymbol(target: ts.Symbol, source: ts.Symbol, unidirectional?: boolean): ts.Symbol; + globals: ts.SymbolTable; + nodeGlobals: ts.SymbolTable; +}): DenoForkContext { + return { + hasNodeSourceFile, + getGlobalsForName, + mergeGlobalSymbolTable, + combinedGlobals: createNodeGlobalsSymbolTable(), + }; + + function hasNodeSourceFile(node: ts.Node | undefined) { + if (!node) return false; + const sourceFile = ts.getSourceFileOfNode(node); + return isNodeSourceFile(sourceFile); + } + + function getGlobalsForName(id: ts.__String) { + return nodeOnlyGlobalNames.has(id) ? nodeGlobals : globals; + } + + function mergeGlobalSymbolTable(node: ts.Node, source: ts.SymbolTable, unidirectional = false) { + const sourceFile = ts.getSourceFileOfNode(node); + const isNodeFile = hasNodeSourceFile(sourceFile); + source.forEach((sourceSymbol, id) => { + const target = isNodeFile ? getGlobalsForName(id) : globals; + const targetSymbol = target.get(id); + target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol); + }); + } + + function createNodeGlobalsSymbolTable() { + return new Proxy(globals, { + get(target, prop: string | symbol, receiver) { + if (prop === "get") { + return (key: ts.__String) => { + return nodeGlobals.get(key) ?? globals.get(key); + }; + } + else if (prop === "has") { + return (key: ts.__String) => { + return nodeGlobals.has(key) || globals.has(key); + }; + } + else if (prop === "size") { + let i = 0; + for (const _ignore of getEntries(entry => entry)) { + i++; + } + return i; + } + else if (prop === "forEach") { + return (action: (value: ts.Symbol, key: ts.__String) => void) => { + for (const [key, value] of getEntries(entry => entry)) { + action(value, key); + } + }; + } + else if (prop === "entries") { + return () => { + return getEntries(kv => kv); + }; + } + else if (prop === "keys") { + return () => { + return getEntries(kv => kv[0]); + }; + } + else if (prop === "values") { + return () => { + return getEntries(kv => kv[1]); + }; + } + else if (prop === Symbol.iterator) { + return () => { + // Need to convert this to an array since typescript targets ES5 + // and providing back the iterator won't work here. I don't want + // to change the target to ES6 because I'm not sure if that would + // surface any issues. + return Array.from(getEntries(kv => kv))[Symbol.iterator](); + }; + } + else { + const value = (target as any)[prop]; + if (value instanceof Function) { + return function (this: any, ...args: any[]) { + return value.apply(this === receiver ? target : this, args); + }; + } + return value; + } + }, + }); + + function* getEntries( + transform: (value: [ts.__String, ts.Symbol]) => R, + ) { + const foundKeys = new Set(); + // prefer the node globals over the deno globalThis + for (const entries of [nodeGlobals.entries(), globals.entries()]) { + for (const entry of entries) { + if (!foundKeys.has(entry[0])) { + yield transform(entry); + foundKeys.add(entry[0]); + } + } + } + } + } +} + +export interface NpmPackageReference { + name: string; + versionReq: string; + subPath: string | undefined; +} + +export function tryParseNpmPackageReference(text: string) { + try { + return parseNpmPackageReference(text); + } + catch { + return undefined; + } +} + +export function parseNpmPackageReference(text: string) { + if (!text.startsWith("npm:")) { + throw new Error(`Not an npm specifier: ${text}`); + } + text = text.replace(/^npm:\/?/, ""); // todo: remove this regex + const parts = text.split("/"); + const namePartLen = text.startsWith("@") ? 2 : 1; + if (parts.length < namePartLen) { + throw new Error(`Not a valid package: ${text}`); + } + const nameParts = parts.slice(0, namePartLen); + const lastNamePart = nameParts.at(-1)!; + const lastAtIndex = lastNamePart.lastIndexOf("@"); + let versionReq: string | undefined; + if (lastAtIndex > 0) { + versionReq = lastNamePart.substring(lastAtIndex + 1); + nameParts[nameParts.length - 1] = lastNamePart.substring(0, lastAtIndex); + } + const name = nameParts.join("/"); + if (name.length === 0) { + throw new Error(`Npm specifier did not have a name: ${text}`); + } + return { + name, + versionReq, + subPath: parts.length > nameParts.length ? parts.slice(nameParts.length).join("/") : undefined, + }; +} diff --git a/src/compiler/path.ts b/src/compiler/path.ts index b05216adc47b5..9af8fcb7db285 100644 --- a/src/compiler/path.ts +++ b/src/compiler/path.ts @@ -216,6 +216,11 @@ function getEncodedRootLength(path: string): number { return ~path.length; // URL: "file://server", "http://server" } + // deno: temporary hack until https://github.com/microsoft/TypeScript/issues/53605 is fixed + if (path.startsWith("data:")) { + return ~path.length; + } + // relative return 0; } @@ -706,6 +711,11 @@ export function ensureTrailingDirectorySeparator(path: string): string; /** @internal */ export function ensureTrailingDirectorySeparator(path: string) { if (!hasTrailingDirectorySeparator(path)) { + // deno: added this so that data urls don't get a trailing slash + // https://github.com/microsoft/TypeScript/issues/53605#issuecomment-1492167313 + if (path.startsWith("data:")) { + return path; + } return path + directorySeparator; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 04855abd9f053..433f9ab1670db 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5219,7 +5219,7 @@ export interface TypeChecker { /** @internal */ forEachExportAndPropertyOfModule(moduleSymbol: Symbol, cb: (symbol: Symbol, key: __String) => void): void; getJsxIntrinsicTagNamesAt(location: Node): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; - getAmbientModules(): Symbol[]; + getAmbientModules(sourceFile?: SourceFile): Symbol[]; tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined; /** diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index debbf655c9947..501c4aae9db26 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -91,6 +91,7 @@ import { DeclarationWithTypeParameters, Decorator, DefaultClause, + deno, DestructuringAssignment, Diagnostic, DiagnosticArguments, @@ -11368,7 +11369,9 @@ export function createNameResolver({ argumentsSymbol, error, getSymbolOfDeclaration, - globals, + denoGlobals, + nodeGlobals, + denoContext, lookup, setRequiresScopeChangeCache = returnUndefined, getRequiresScopeChangeCache = returnUndefined, @@ -11751,7 +11754,12 @@ export function createNameResolver({ } if (!excludeGlobals) { - result = lookup(globals, name, meaning); + if (denoContext.hasNodeSourceFile(lastLocation)) { + result = lookup(nodeGlobals, name, meaning); + } + if (!result) { + result = lookup(denoGlobals, name, meaning); + } } } if (!result) { diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 11ebfb0c6793f..f650665d0c036 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -19105,6 +19105,7 @@ declare var ReadableStream: { new(underlyingSource: UnderlyingByteSource, strategy?: { highWaterMark?: number }): ReadableStream; new(underlyingSource: UnderlyingDefaultSource, strategy?: QueuingStrategy): ReadableStream; new(underlyingSource?: UnderlyingSource, strategy?: QueuingStrategy): ReadableStream; + from(asyncIterable: AsyncIterable | Iterable>): ReadableStream; }; /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader) */ diff --git a/src/lib/es2020.intl.d.ts b/src/lib/es2020.intl.d.ts index 5ab347994647e..5543b39ccc752 100644 --- a/src/lib/es2020.intl.d.ts +++ b/src/lib/es2020.intl.d.ts @@ -269,7 +269,7 @@ declare namespace Intl { } interface DateTimeFormatOptions { - calendar?: string | undefined; + calendar?: string | (typeof globalThis extends { Temporal: { CalendarProtocol: infer T; }; } ? T : undefined) | undefined; dayPeriod?: "narrow" | "short" | "long" | undefined; numberingSystem?: string | undefined; diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index ab484e1812e7b..1b6593d003288 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -4490,7 +4490,7 @@ declare namespace Intl { timeZoneName?: "short" | "long" | "shortOffset" | "longOffset" | "shortGeneric" | "longGeneric" | undefined; formatMatcher?: "best fit" | "basic" | undefined; hour12?: boolean | undefined; - timeZone?: string | undefined; + timeZone?: string | (typeof globalThis extends { Temporal: { TimeZoneProtocol: infer T; }; } ? T : undefined) | undefined; } interface ResolvedDateTimeFormatOptions { diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index fb07902309138..e8a87a2c6c209 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -5093,6 +5093,7 @@ declare var ReadableStream: { new(underlyingSource: UnderlyingByteSource, strategy?: { highWaterMark?: number }): ReadableStream; new(underlyingSource: UnderlyingDefaultSource, strategy?: QueuingStrategy): ReadableStream; new(underlyingSource?: UnderlyingSource, strategy?: QueuingStrategy): ReadableStream; + from(asyncIterable: AsyncIterable | Iterable>): ReadableStream; }; /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader) */ diff --git a/src/services/completions.ts b/src/services/completions.ts index 30e9ad40bf3f1..e44524e08d1f9 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -5825,7 +5825,8 @@ function isProbablyGlobalType(type: Type, sourceFile: SourceFile, checker: TypeC if (globalSymbol && checker.getTypeOfSymbolAtLocation(globalSymbol, sourceFile) === type) { return true; } - const globalThisSymbol = checker.resolveName("globalThis", /*location*/ undefined, SymbolFlags.Value, /*excludeGlobals*/ false); + // deno: provide sourceFile so that it can figure out if it's a node or deno globalThis + const globalThisSymbol = checker.resolveName("globalThis", /*location*/ sourceFile, SymbolFlags.Value, /*excludeGlobals*/ false); if (globalThisSymbol && checker.getTypeOfSymbolAtLocation(globalThisSymbol, sourceFile) === type) { return true; } From bf17c62cfd79ca3f2dca413f7f666708d7ec0deb Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 20 Nov 2024 10:35:14 -0500 Subject: [PATCH 02/14] updates --- src/compiler/deno.ts | 10 +++++----- src/compiler/utilities.ts | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts index 32e938c119e7d..908299be761f1 100644 --- a/src/compiler/deno.ts +++ b/src/compiler/deno.ts @@ -5,11 +5,11 @@ export type IsNodeSourceFileCallback = (sourceFile: ts.SourceFile) => boolean; let isNodeSourceFile: IsNodeSourceFileCallback = () => false; let nodeOnlyGlobalNames = new Set(); -export function setIsNodeSourceFileCallback(callback: IsNodeSourceFileCallback) { +export function setIsNodeSourceFileCallback(callback: IsNodeSourceFileCallback): void { isNodeSourceFile = callback; } -export function setNodeOnlyGlobalNames(names: readonly string[]) { +export function setNodeOnlyGlobalNames(names: readonly string[]): void { nodeOnlyGlobalNames = new Set(names) as Set; } @@ -143,11 +143,11 @@ export function createDenoForkContext({ export interface NpmPackageReference { name: string; - versionReq: string; + versionReq: string | undefined; subPath: string | undefined; } -export function tryParseNpmPackageReference(text: string) { +export function tryParseNpmPackageReference(text: string): NpmPackageReference | undefined { try { return parseNpmPackageReference(text); } @@ -156,7 +156,7 @@ export function tryParseNpmPackageReference(text: string) { } } -export function parseNpmPackageReference(text: string) { +export function parseNpmPackageReference(text: string): NpmPackageReference { if (!text.startsWith("npm:")) { throw new Error(`Not an npm specifier: ${text}`); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 501c4aae9db26..766afc1f0ae53 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -11341,7 +11341,9 @@ export interface NameResolverOptions { compilerOptions: CompilerOptions; getSymbolOfDeclaration: (node: Declaration) => Symbol; error: (location: Node | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments) => void; - globals: SymbolTable; + denoGlobals: SymbolTable; + nodeGlobals: SymbolTable; + denoContext: deno.DenoForkContext; argumentsSymbol: Symbol; requireSymbol: Symbol; lookup: (symbols: SymbolTable, name: __String, meaning: SymbolFlags) => Symbol | undefined; From 4f6e3c15b7219a3527b1e9222be89c1bf5854f72 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 28 Jan 2025 16:34:40 -0500 Subject: [PATCH 03/14] Add extension --- src/compiler/deno.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts index 908299be761f1..b209248cf1e51 100644 --- a/src/compiler/deno.ts +++ b/src/compiler/deno.ts @@ -1,4 +1,4 @@ -import * as ts from "./_namespaces/ts"; +import * as ts from "./_namespaces/ts.js"; export type IsNodeSourceFileCallback = (sourceFile: ts.SourceFile) => boolean; From d495f82c33af61530abb2049998916a617b31a70 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 28 Jan 2025 16:47:12 -0500 Subject: [PATCH 04/14] Remove unnecessary code that we don't use --- src/typescript/_namespaces/ts.server.ts | 4 ---- src/typescript/_namespaces/ts.ts | 5 ----- src/typescript/tsconfig.json | 5 +---- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/typescript/_namespaces/ts.server.ts b/src/typescript/_namespaces/ts.server.ts index 6e53b0a9aef37..e69de29bb2d1d 100644 --- a/src/typescript/_namespaces/ts.server.ts +++ b/src/typescript/_namespaces/ts.server.ts @@ -1,4 +0,0 @@ -/* Generated file to emulate the ts.server namespace. */ - -export * from "../../jsTyping/_namespaces/ts.server.js"; -export * from "../../server/_namespaces/ts.server.js"; diff --git a/src/typescript/_namespaces/ts.ts b/src/typescript/_namespaces/ts.ts index 1c1a9fcb82264..67be3307c1ecc 100644 --- a/src/typescript/_namespaces/ts.ts +++ b/src/typescript/_namespaces/ts.ts @@ -1,8 +1,3 @@ /* Generated file to emulate the ts namespace. */ export * from "../../compiler/_namespaces/ts.js"; -export * from "../../jsTyping/_namespaces/ts.js"; -export * from "../../services/_namespaces/ts.js"; -export * from "../../server/_namespaces/ts.js"; -import * as server from "./ts.server.js"; -export { server }; diff --git a/src/typescript/tsconfig.json b/src/typescript/tsconfig.json index 20b8306af53eb..e0e98fac65db6 100644 --- a/src/typescript/tsconfig.json +++ b/src/typescript/tsconfig.json @@ -3,10 +3,7 @@ "compilerOptions": { }, "references": [ - { "path": "../compiler" }, - { "path": "../jsTyping" }, - { "path": "../services" }, - { "path": "../server" } + { "path": "../compiler" } ], "include": ["**/*"] } From 3127de668e91f34e90ae96ad059db01167192bb0 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 28 Jan 2025 21:15:17 -0500 Subject: [PATCH 05/14] Add back services --- src/typescript/_namespaces/ts.ts | 2 ++ src/typescript/tsconfig.json | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/typescript/_namespaces/ts.ts b/src/typescript/_namespaces/ts.ts index 67be3307c1ecc..8e5b800231e5b 100644 --- a/src/typescript/_namespaces/ts.ts +++ b/src/typescript/_namespaces/ts.ts @@ -1,3 +1,5 @@ /* Generated file to emulate the ts namespace. */ export * from "../../compiler/_namespaces/ts.js"; +export * from "../../services/_namespaces/ts.js"; + diff --git a/src/typescript/tsconfig.json b/src/typescript/tsconfig.json index e0e98fac65db6..f88a5f48404b2 100644 --- a/src/typescript/tsconfig.json +++ b/src/typescript/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { }, "references": [ - { "path": "../compiler" } + { "path": "../compiler" }, + { "path": "../services" } ], "include": ["**/*"] } From 4248e501d6f4669ef59f3d2c83306ab96b942607 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Thu, 30 Jan 2025 20:35:49 -0500 Subject: [PATCH 06/14] committing this before revert --- src/compiler/checker.ts | 35 +++----------- src/compiler/deno.ts | 105 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b0a16431a5d32..f34a83d53a3a4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1545,43 +1545,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { denoGlobalThisSymbol.declarations = []; denoGlobals.set(denoGlobalThisSymbol.escapedName, denoGlobalThisSymbol); - const denoContext = deno.createDenoForkContext({ + var denoContext = deno.createDenoForkContext({ globals: denoGlobals, nodeGlobals, mergeSymbol, }); - const nodeGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); + denoContext.preProcessSourceFiles(host.getSourceFiles()); + + var nodeGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); nodeGlobalThisSymbol.exports = denoContext.combinedGlobals; nodeGlobalThisSymbol.declarations = []; nodeGlobals.set(nodeGlobalThisSymbol.escapedName, nodeGlobalThisSymbol); - // deno: huge hacks to get @types/node to work - nodeGlobals.set( - "onmessage" as __String, - createSymbol(SymbolFlags.Module, "onmessage" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "onabort" as __String, - createSymbol(SymbolFlags.Module, "onabort" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "ReportingObserver" as __String, - createSymbol(SymbolFlags.Module, "ReportingObserver" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "PerformanceObserver" as __String, - createSymbol(SymbolFlags.Module, "PerformanceObserver" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "PerformanceObserverEntryList" as __String, - createSymbol(SymbolFlags.Module, "PerformanceObserverEntryList" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "PerformanceResourceTiming" as __String, - createSymbol(SymbolFlags.Module, "PerformanceResourceTiming" as __String, CheckFlags.Readonly), - ); - var argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String); var requireSymbol = createSymbol(SymbolFlags.Property, "require" as __String); var isolatedModulesLikeFlagName = compilerOptions.verbatimModuleSyntax ? "verbatimModuleSyntax" : "isolatedModules"; @@ -34542,7 +34518,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. if (symbol) return symbol; let candidates: Symbol[]; - if (symbols === denoGlobals || symbols == nodeGlobals) { + if (symbols === denoGlobals || symbols === nodeGlobals) { const primitives = mapDefined( ["string", "number", "boolean", "object", "bigint", "symbol"], s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as __String) @@ -44376,6 +44352,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ? Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2 : Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2; const declName = declarationNameToString(nextDeclarationName); + (globalThis as any).Deno.core.print("Error for: " + declName + "\n"); const err = error( nextDeclarationName, message, diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts index b209248cf1e51..ecd8aa995a9f8 100644 --- a/src/compiler/deno.ts +++ b/src/compiler/deno.ts @@ -23,6 +23,7 @@ export interface DenoForkContext { getGlobalsForName: (id: ts.__String) => ts.SymbolTable; mergeGlobalSymbolTable: (node: ts.Node, source: ts.SymbolTable, unidirectional?: boolean) => void; combinedGlobals: ts.SymbolTable; + preProcessSourceFiles: (files: readonly ts.SourceFile[]) => void; } export function createDenoForkContext({ @@ -39,6 +40,7 @@ export function createDenoForkContext({ getGlobalsForName, mergeGlobalSymbolTable, combinedGlobals: createNodeGlobalsSymbolTable(), + preProcessSourceFiles, }; function hasNodeSourceFile(node: ts.Node | undefined) { @@ -139,6 +141,109 @@ export function createDenoForkContext({ } } } + + function preProcessSourceFiles(files: readonly ts.SourceFile[]) { + for (const sourceFile of files) { + if (sourceFile.path.endsWith(".d.ts") && hasNodeSourceFile(sourceFile) && sourceFile.path.includes("/@types/node/")) { + processTypesNodeFile(sourceFile); + } + } + } + + function processTypesNodeFile(sourceFile: ts.SourceFile) { + function makeNodeWhitespace(node: ts.Node) { + sourceFile.text = sourceFile.text.slice(0, node.pos) + + " ".repeat(node.pos + node.end) + + sourceFile.text.slice(node.end); + } + + const globalNames = new Set([ + "TextDecoder" as ts.__String, + "TextEncoder", + ]); + (globalThis as any).Deno.core.print("Looking at: " + sourceFile.path + "\n"); + for (const stmt of sourceFile.statements) { + searchGlobalAugmentationInStmt(stmt); + } + + function searchGlobalAugmentationInStmt(stmt: ts.Statement) { + if (!ts.isModuleDeclaration(stmt) || stmt.body === undefined || !ts.isModuleBlock(stmt.body)) { + return; + } + + if (ts.isGlobalScopeAugmentation(stmt)) { + for (let i = stmt.body.statements.length - 1; i >= 0; i--) { + const childStmt = stmt.body.statements[i]; + if (shouldRemoveStmt(childStmt)) { + // makeNodeWhitespace(childStmt); + // (stmt.body.statements as any as unknown[]).splice(i, 1); + // (globalThis as any).Deno.core.print("DATA: " + JSON.stringify(sourceFile, undefined, 2) + "\n"); + } + } + } + else { + for (const child of stmt.body.statements) { + searchGlobalAugmentationInStmt(child); + } + } + } + + function shouldRemoveStmt(stmt: ts.Statement) { + if (!ts.isVariableStatement(stmt)) { + return false; + } + for (let i = stmt.declarationList.declarations.length - 1; i >= 0; i--) { + const varDecl = stmt.declarationList.declarations[i]; + if (shouldRemoveVarDecl(varDecl)) { + if (ts.isIdentifier(varDecl.name)) { + if (stmt.declarationList.declarations.length === 1) { + return true; + } + else { + (stmt.declarationList.declarations as any as unknown[]).splice(i, 1); + } + } + } + } + return false; + } + + function shouldRemoveVarDecl(decl: ts.VariableDeclaration) { + if (ts.isIdentifier(decl.name) && decl.type) { + if ( + decl.name.escapedText === "PerformanceObserver" + || decl.name.escapedText === "PerformanceObserverEntryList" + || decl.name.escapedText === "PerformanceResourceTiming" + ) { + return; + } + if (ts.isConditionalTypeNode(decl.type) && ts.isTypeQueryNode(decl.type.checkType)) { + if (ts.isTypeLiteralNode(decl.type.extendsType)) { + const typeLit = decl.type.extendsType; + for (let i = typeLit.members.length - 1; i >= 0; i--) { + const member = typeLit.members[i]; + if (member.name && ts.isIdentifier(member.name)) { + if (member.name.escapedText === "onmessage" || member.name.escapedText === "onabort") { + (member.name as any).escapedText = "Deno"; + (globalThis as any).Deno.core.print("REMOVED: " + decl.name.escapedText + "\n"); + } + else if (member.name.escapedText === "ReportingObserver") { + (typeLit.members as any as any[]).splice(i, 1); + } + } + } + } + // return ts.isIdentifier(checkType.exprName) && checkType.exprName.escapedText === "globalThis"; + // (globalThis as any).Deno.core.print("Looking at: " + decl.name.escapedText + "\n"); + // if (globalNames.has(decl.name.escapedText)) { + // (globalThis as any).Deno.core.print("REMOVED: " + decl.name.escapedText + "\n"); + // return true; + // } + } + } + return false; + } + } } export interface NpmPackageReference { From f817bd26786b84260e8df66d77b320469405059f Mon Sep 17 00:00:00 2001 From: David Sherret Date: Thu, 30 Jan 2025 20:36:22 -0500 Subject: [PATCH 07/14] Revert "committing this before revert" This reverts commit 4248e501d6f4669ef59f3d2c83306ab96b942607. --- src/compiler/checker.ts | 35 +++++++++++--- src/compiler/deno.ts | 105 ---------------------------------------- 2 files changed, 29 insertions(+), 111 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f34a83d53a3a4..b0a16431a5d32 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1545,19 +1545,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { denoGlobalThisSymbol.declarations = []; denoGlobals.set(denoGlobalThisSymbol.escapedName, denoGlobalThisSymbol); - var denoContext = deno.createDenoForkContext({ + const denoContext = deno.createDenoForkContext({ globals: denoGlobals, nodeGlobals, mergeSymbol, }); - denoContext.preProcessSourceFiles(host.getSourceFiles()); - - var nodeGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); + const nodeGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); nodeGlobalThisSymbol.exports = denoContext.combinedGlobals; nodeGlobalThisSymbol.declarations = []; nodeGlobals.set(nodeGlobalThisSymbol.escapedName, nodeGlobalThisSymbol); + // deno: huge hacks to get @types/node to work + nodeGlobals.set( + "onmessage" as __String, + createSymbol(SymbolFlags.Module, "onmessage" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "onabort" as __String, + createSymbol(SymbolFlags.Module, "onabort" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "ReportingObserver" as __String, + createSymbol(SymbolFlags.Module, "ReportingObserver" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "PerformanceObserver" as __String, + createSymbol(SymbolFlags.Module, "PerformanceObserver" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "PerformanceObserverEntryList" as __String, + createSymbol(SymbolFlags.Module, "PerformanceObserverEntryList" as __String, CheckFlags.Readonly), + ); + nodeGlobals.set( + "PerformanceResourceTiming" as __String, + createSymbol(SymbolFlags.Module, "PerformanceResourceTiming" as __String, CheckFlags.Readonly), + ); + var argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String); var requireSymbol = createSymbol(SymbolFlags.Property, "require" as __String); var isolatedModulesLikeFlagName = compilerOptions.verbatimModuleSyntax ? "verbatimModuleSyntax" : "isolatedModules"; @@ -34518,7 +34542,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. if (symbol) return symbol; let candidates: Symbol[]; - if (symbols === denoGlobals || symbols === nodeGlobals) { + if (symbols === denoGlobals || symbols == nodeGlobals) { const primitives = mapDefined( ["string", "number", "boolean", "object", "bigint", "symbol"], s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as __String) @@ -44352,7 +44376,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ? Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2 : Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2; const declName = declarationNameToString(nextDeclarationName); - (globalThis as any).Deno.core.print("Error for: " + declName + "\n"); const err = error( nextDeclarationName, message, diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts index ecd8aa995a9f8..b209248cf1e51 100644 --- a/src/compiler/deno.ts +++ b/src/compiler/deno.ts @@ -23,7 +23,6 @@ export interface DenoForkContext { getGlobalsForName: (id: ts.__String) => ts.SymbolTable; mergeGlobalSymbolTable: (node: ts.Node, source: ts.SymbolTable, unidirectional?: boolean) => void; combinedGlobals: ts.SymbolTable; - preProcessSourceFiles: (files: readonly ts.SourceFile[]) => void; } export function createDenoForkContext({ @@ -40,7 +39,6 @@ export function createDenoForkContext({ getGlobalsForName, mergeGlobalSymbolTable, combinedGlobals: createNodeGlobalsSymbolTable(), - preProcessSourceFiles, }; function hasNodeSourceFile(node: ts.Node | undefined) { @@ -141,109 +139,6 @@ export function createDenoForkContext({ } } } - - function preProcessSourceFiles(files: readonly ts.SourceFile[]) { - for (const sourceFile of files) { - if (sourceFile.path.endsWith(".d.ts") && hasNodeSourceFile(sourceFile) && sourceFile.path.includes("/@types/node/")) { - processTypesNodeFile(sourceFile); - } - } - } - - function processTypesNodeFile(sourceFile: ts.SourceFile) { - function makeNodeWhitespace(node: ts.Node) { - sourceFile.text = sourceFile.text.slice(0, node.pos) - + " ".repeat(node.pos + node.end) - + sourceFile.text.slice(node.end); - } - - const globalNames = new Set([ - "TextDecoder" as ts.__String, - "TextEncoder", - ]); - (globalThis as any).Deno.core.print("Looking at: " + sourceFile.path + "\n"); - for (const stmt of sourceFile.statements) { - searchGlobalAugmentationInStmt(stmt); - } - - function searchGlobalAugmentationInStmt(stmt: ts.Statement) { - if (!ts.isModuleDeclaration(stmt) || stmt.body === undefined || !ts.isModuleBlock(stmt.body)) { - return; - } - - if (ts.isGlobalScopeAugmentation(stmt)) { - for (let i = stmt.body.statements.length - 1; i >= 0; i--) { - const childStmt = stmt.body.statements[i]; - if (shouldRemoveStmt(childStmt)) { - // makeNodeWhitespace(childStmt); - // (stmt.body.statements as any as unknown[]).splice(i, 1); - // (globalThis as any).Deno.core.print("DATA: " + JSON.stringify(sourceFile, undefined, 2) + "\n"); - } - } - } - else { - for (const child of stmt.body.statements) { - searchGlobalAugmentationInStmt(child); - } - } - } - - function shouldRemoveStmt(stmt: ts.Statement) { - if (!ts.isVariableStatement(stmt)) { - return false; - } - for (let i = stmt.declarationList.declarations.length - 1; i >= 0; i--) { - const varDecl = stmt.declarationList.declarations[i]; - if (shouldRemoveVarDecl(varDecl)) { - if (ts.isIdentifier(varDecl.name)) { - if (stmt.declarationList.declarations.length === 1) { - return true; - } - else { - (stmt.declarationList.declarations as any as unknown[]).splice(i, 1); - } - } - } - } - return false; - } - - function shouldRemoveVarDecl(decl: ts.VariableDeclaration) { - if (ts.isIdentifier(decl.name) && decl.type) { - if ( - decl.name.escapedText === "PerformanceObserver" - || decl.name.escapedText === "PerformanceObserverEntryList" - || decl.name.escapedText === "PerformanceResourceTiming" - ) { - return; - } - if (ts.isConditionalTypeNode(decl.type) && ts.isTypeQueryNode(decl.type.checkType)) { - if (ts.isTypeLiteralNode(decl.type.extendsType)) { - const typeLit = decl.type.extendsType; - for (let i = typeLit.members.length - 1; i >= 0; i--) { - const member = typeLit.members[i]; - if (member.name && ts.isIdentifier(member.name)) { - if (member.name.escapedText === "onmessage" || member.name.escapedText === "onabort") { - (member.name as any).escapedText = "Deno"; - (globalThis as any).Deno.core.print("REMOVED: " + decl.name.escapedText + "\n"); - } - else if (member.name.escapedText === "ReportingObserver") { - (typeLit.members as any as any[]).splice(i, 1); - } - } - } - } - // return ts.isIdentifier(checkType.exprName) && checkType.exprName.escapedText === "globalThis"; - // (globalThis as any).Deno.core.print("Looking at: " + decl.name.escapedText + "\n"); - // if (globalNames.has(decl.name.escapedText)) { - // (globalThis as any).Deno.core.print("REMOVED: " + decl.name.escapedText + "\n"); - // return true; - // } - } - } - return false; - } - } } export interface NpmPackageReference { From b24e6f34d385fefbb98e01144289eeb4918ca5f4 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Thu, 30 Jan 2025 20:59:19 -0500 Subject: [PATCH 08/14] Add ability to ignore certain symbols in @types/node from being added to globalThis --- src/compiler/checker.ts | 26 -------------------------- src/compiler/deno.ts | 13 +++++++++++-- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b0a16431a5d32..e45fc0e8896eb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1556,32 +1556,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { nodeGlobalThisSymbol.declarations = []; nodeGlobals.set(nodeGlobalThisSymbol.escapedName, nodeGlobalThisSymbol); - // deno: huge hacks to get @types/node to work - nodeGlobals.set( - "onmessage" as __String, - createSymbol(SymbolFlags.Module, "onmessage" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "onabort" as __String, - createSymbol(SymbolFlags.Module, "onabort" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "ReportingObserver" as __String, - createSymbol(SymbolFlags.Module, "ReportingObserver" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "PerformanceObserver" as __String, - createSymbol(SymbolFlags.Module, "PerformanceObserver" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "PerformanceObserverEntryList" as __String, - createSymbol(SymbolFlags.Module, "PerformanceObserverEntryList" as __String, CheckFlags.Readonly), - ); - nodeGlobals.set( - "PerformanceResourceTiming" as __String, - createSymbol(SymbolFlags.Module, "PerformanceResourceTiming" as __String, CheckFlags.Readonly), - ); - var argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String); var requireSymbol = createSymbol(SymbolFlags.Property, "require" as __String); var isolatedModulesLikeFlagName = compilerOptions.verbatimModuleSyntax ? "verbatimModuleSyntax" : "isolatedModules"; diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts index b209248cf1e51..aa5c7f18c0359 100644 --- a/src/compiler/deno.ts +++ b/src/compiler/deno.ts @@ -4,13 +4,18 @@ export type IsNodeSourceFileCallback = (sourceFile: ts.SourceFile) => boolean; let isNodeSourceFile: IsNodeSourceFileCallback = () => false; let nodeOnlyGlobalNames = new Set(); +let typesNodeIgnorableNames = new Set(); export function setIsNodeSourceFileCallback(callback: IsNodeSourceFileCallback): void { isNodeSourceFile = callback; } -export function setNodeOnlyGlobalNames(names: readonly string[]): void { - nodeOnlyGlobalNames = new Set(names) as Set; +export function setNodeOnlyGlobalNames(names: Set): void { + nodeOnlyGlobalNames = names as Set; +} + +export function setTypesNodeIgnorableNames(names: Set): void { + typesNodeIgnorableNames = names as Set; } // When upgrading: @@ -54,9 +59,13 @@ export function createDenoForkContext({ function mergeGlobalSymbolTable(node: ts.Node, source: ts.SymbolTable, unidirectional = false) { const sourceFile = ts.getSourceFileOfNode(node); const isNodeFile = hasNodeSourceFile(sourceFile); + const isTypesNodeSourceFile = isNodeFile && sourceFile.path.endsWith(".d.ts") && sourceFile.path.includes("/@types/node/"); source.forEach((sourceSymbol, id) => { const target = isNodeFile ? getGlobalsForName(id) : globals; const targetSymbol = target.get(id); + if (isTypesNodeSourceFile && targetSymbol !== undefined && typesNodeIgnorableNames.has(id)) { + return; + } target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol); }); } From 0ae7103488b297eb0ea8f23bd8998fd0fcbfa64a Mon Sep 17 00:00:00 2001 From: David Sherret Date: Thu, 30 Jan 2025 21:23:56 -0500 Subject: [PATCH 09/14] var --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e45fc0e8896eb..ff3f695cb464a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1551,7 +1551,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { mergeSymbol, }); - const nodeGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); + var nodeGlobalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly); nodeGlobalThisSymbol.exports = denoContext.combinedGlobals; nodeGlobalThisSymbol.declarations = []; nodeGlobals.set(nodeGlobalThisSymbol.escapedName, nodeGlobalThisSymbol); From e3e34dbc130e3f08227e5245658a3c3b821f16fe Mon Sep 17 00:00:00 2001 From: David Sherret Date: Thu, 30 Jan 2025 22:24:56 -0500 Subject: [PATCH 10/14] allow merging to global if previously created in @types/node --- src/compiler/deno.ts | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts index aa5c7f18c0359..e38c13c6c9caf 100644 --- a/src/compiler/deno.ts +++ b/src/compiler/deno.ts @@ -59,17 +59,42 @@ export function createDenoForkContext({ function mergeGlobalSymbolTable(node: ts.Node, source: ts.SymbolTable, unidirectional = false) { const sourceFile = ts.getSourceFileOfNode(node); const isNodeFile = hasNodeSourceFile(sourceFile); - const isTypesNodeSourceFile = isNodeFile && sourceFile.path.endsWith(".d.ts") && sourceFile.path.includes("/@types/node/"); + const isTypesNodeSourceFile = isNodeFile && isTypesNodePkgPath(sourceFile.path); source.forEach((sourceSymbol, id) => { const target = isNodeFile ? getGlobalsForName(id) : globals; const targetSymbol = target.get(id); - if (isTypesNodeSourceFile && targetSymbol !== undefined && typesNodeIgnorableNames.has(id)) { + if ( + isTypesNodeSourceFile + && targetSymbol !== undefined + && typesNodeIgnorableNames.has(id) + // if the symbol has a @types/node package then that means the global + // was created within the @types/node package and not the lib.d.ts files, + // so allow merging to it (useful when someone has DOM and deno types disabled) + && !symbolHasAnyTypesNodePkgDecl(targetSymbol) + ) { return; } target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol); }); } + function symbolHasAnyTypesNodePkgDecl(symbol: ts.Symbol) { + if (symbol.declarations) { + for (const decl of symbol.declarations) { + const sourceFile = ts.getSourceFileOfNode(decl); + const isNodeFile = hasNodeSourceFile(sourceFile); + if (isNodeFile && isTypesNodePkgPath(sourceFile.path)) { + return true; + } + } + } + return false; + } + + function isTypesNodePkgPath(path: ts.Path) { + return path.endsWith(".d.ts") && path.includes("/@types/node/"); + } + function createNodeGlobalsSymbolTable() { return new Proxy(globals, { get(target, prop: string | symbol, receiver) { From cc47f9d585e0c90a3b3ba54be9149fbeda1ff541 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Tue, 11 Feb 2025 13:28:21 +0100 Subject: [PATCH 11/14] add deno tracing api --- src/compiler/deno.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/compiler/deno.ts b/src/compiler/deno.ts index e38c13c6c9caf..956127e2a6042 100644 --- a/src/compiler/deno.ts +++ b/src/compiler/deno.ts @@ -6,6 +6,38 @@ let isNodeSourceFile: IsNodeSourceFileCallback = () => false; let nodeOnlyGlobalNames = new Set(); let typesNodeIgnorableNames = new Set(); +export type EnterSpan = (name: string) => object; +export type ExitSpan = (span: object) => void; + +export let enterSpan: EnterSpan = () => ({ }); +export let exitSpan: ExitSpan = () => { }; + +export function setEnterSpan(f: EnterSpan): void { + enterSpan = f; +} +export function setExitSpan(f: ExitSpan): void { + exitSpan = f; +} + +export function spanned(name: string, f: () => T): T { + const span = enterSpan(name); + let needsExit = true; + try { + const result = f(); + if (result instanceof Promise) { + needsExit = false; + return result.finally(() => exitSpan(span)) as T; + } else { + return result; + } + + } finally { + if (needsExit) { + exitSpan(span); + } + } +} + export function setIsNodeSourceFileCallback(callback: IsNodeSourceFileCallback): void { isNodeSourceFile = callback; } From b5373e76f7401185fb145d1f708ce500ff261d84 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Thu, 13 Feb 2025 16:47:02 +0100 Subject: [PATCH 12/14] Disable fileExists cache --- src/compiler/program.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 45d8539f581e3..78f3ba9335cfd 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -577,15 +577,16 @@ export function changeCompilerHostLikeToUseCache( return sourceFile; } : undefined; + // deno: disable this cache because we always return false here // fileExists for any kind of extension - host.fileExists = fileName => { - const key = toPath(fileName); - const value = fileExistsCache.get(key); - if (value !== undefined) return value; - const newValue = originalFileExists.call(host, fileName); - fileExistsCache.set(key, !!newValue); - return newValue; - }; + // host.fileExists = fileName => { + // const key = toPath(fileName); + // const value = fileExistsCache.get(key); + // if (value !== undefined) return value; + // const newValue = originalFileExists.call(host, fileName); + // fileExistsCache.set(key, !!newValue); + // return newValue; + // }; if (originalWriteFile) { host.writeFile = (fileName, data, ...rest) => { const key = toPath(fileName); From dc74337df6360ea807f8ff08c60a709f4e4ce23f Mon Sep 17 00:00:00 2001 From: David Sherret Date: Fri, 21 Feb 2025 18:26:51 -0500 Subject: [PATCH 13/14] export createCacheableExportInfoMap --- src/services/exportInfoMap.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index dfd00ce2e9170..28ac05ad8ecc1 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -127,7 +127,6 @@ export interface ExportInfoMap { onFileChanged(oldSourceFile: SourceFile, newSourceFile: SourceFile, typeAcquisitionEnabled: boolean): boolean; } -/** @internal */ export interface CacheableExportInfoMapHost { getCurrentProgram(): Program | undefined; getPackageJsonAutoImportProvider(): Program | undefined; @@ -135,7 +134,6 @@ export interface CacheableExportInfoMapHost { } export type ExportMapInfoKey = string & { __exportInfoKey: void; }; -/** @internal */ export function createCacheableExportInfoMap(host: CacheableExportInfoMapHost): ExportInfoMap { let exportInfoId = 1; const exportInfo = createMultiMap(); From 5ad2342072476a0026bf4f5348ef2dc772f8705c Mon Sep 17 00:00:00 2001 From: David Sherret Date: Fri, 21 Feb 2025 18:37:38 -0500 Subject: [PATCH 14/14] export more needed symbols --- src/services/exportInfoMap.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 28ac05ad8ecc1..b45604bbac9c0 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -68,7 +68,6 @@ export const enum ImportKind { CommonJS, } -/** @internal */ export const enum ExportKind { Named, Default, @@ -77,7 +76,6 @@ export const enum ExportKind { Module, } -/** @internal */ export interface SymbolExportInfo { readonly symbol: Symbol; readonly moduleSymbol: Symbol; @@ -114,7 +112,6 @@ interface CachedSymbolExportInfo { isFromPackageJson: boolean; } -/** @internal */ export interface ExportInfoMap { isUsableByFile(importingFile: Path): boolean; clear(): void;