diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 30460330307a1..f1dedaa84903f 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -1034,6 +1034,17 @@ export const buildAPI = task({ }, }); +async function runCheckAPIDeclarations() { + await run("node", ["./node_modules/typescript/bin/tsc", "-p", "packages/typescript/tsconfig.dist.json"]); +} + +export const checkAPIDeclarations = task({ + name: "check:api-declarations", + description: "Type-checks the emitted @typescript/typescript declaration files.", + dependencies: [buildAPI], + run: runCheckAPIDeclarations, +}); + async function runBuildAPITests(generateSources = true) { if (generateSources) await runGenerateSync(); await run("npm", ["run", "-w", "@typescript/typescript", "build:test"]); @@ -1221,6 +1232,7 @@ export const validate = task({ await runValidation("test:tsc", runTests); await runValidation("test:extension", runTestExtension); + await runValidation("check:api-declarations", runCheckAPIDeclarations); if (options.api || options.all) { if (!options.all) await runGenerateEnums(); await runBuildAPITests(!options.all); @@ -2343,6 +2355,7 @@ async function runBuildNativePreviewPackages() { // Build JS API and copy dist into the package. await run("npm", ["run", "-w", "@typescript/typescript", "build"]); + await runCheckAPIDeclarations(); await cpRecursive(path.join(inputDir, "dist"), path.join(mainPackageDir, "dist")); // Validate that .d.ts files contain no external imports (all imports must start with "." or "#"). @@ -2938,7 +2951,8 @@ async function testVsixPackage(vsixPath, extensionPath, platformPackageName, nod const require = createRequire(process.cwd() + "/extension/node_modules/typescript/package.json"); const manifest = require("./package.json"); for (const mode of ["async", "sync"]) { - const { API } = await import(pathToFileURL(require.resolve(manifest.name + "/unstable/" + mode)).href); + const exportPath = manifest.exports?.["./" + mode] ? mode : "unstable/" + mode; + const { API } = await import(pathToFileURL(require.resolve(manifest.name + "/" + exportPath)).href); const api = new API(); try { assert.ok(await api.parseConfigFile(process.cwd() + "/tsconfig.json")); diff --git a/packages/typescript/package.json b/packages/typescript/package.json index b8034bd929b85..25d720e3d530e 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -41,55 +41,55 @@ "./schemas/tsconfig.schema.json": "./schemas/tsconfig.schema.json", "./schemas/jsconfig.schema.json": "./schemas/jsconfig.schema.json", ".": "./lib/version.cjs", - "./unstable/vscode": { + "./vscode": { "@typescript/source": "./src/vscode/extensionApi.ts", "default": "./dist/vscode/extensionApi.js" }, - "./unstable/sync": { + "./sync": { "@typescript/source": "./src/api/sync/api.ts", "default": "./dist/api/sync/api.js" }, - "./unstable/async": { + "./async": { "@typescript/source": "./src/api/async/api.ts", "default": "./dist/api/async/api.js" }, - "./unstable/fs": { + "./fs": { "@typescript/source": "./src/api/fs.ts", "default": "./dist/api/fs.js" }, - "./unstable/path": { + "./path": { "@typescript/source": "./src/api/typedPaths.ts", "default": "./dist/api/typedPaths.js" }, - "./unstable/proto": { + "./proto": { "@typescript/source": "./src/api/proto.ts", "default": "./dist/api/proto.js" }, - "./unstable/ast": { + "./ast": { "@typescript/source": "./src/ast/index.ts", "default": "./dist/ast/index.js" }, - "./unstable/ast/is": { + "./ast/is": { "@typescript/source": "./src/ast/is.ts", "default": "./dist/ast/is.js" }, - "./unstable/ast/factory": { + "./ast/factory": { "@typescript/source": "./src/ast/factory.generated.ts", "default": "./dist/ast/factory.generated.js" }, - "./unstable/ast/utils": { + "./ast/utils": { "@typescript/source": "./src/ast/utils.ts", "default": "./dist/ast/utils.js" }, - "./unstable/ast/scanner": { + "./ast/scanner": { "@typescript/source": "./src/ast/scanner.ts", "default": "./dist/ast/scanner.js" }, - "./unstable/ast/visitor": { + "./ast/visitor": { "@typescript/source": "./src/ast/visitor.ts", "default": "./dist/ast/visitor.js" }, - "./unstable/ast/clone": { + "./ast/clone": { "@typescript/source": "./src/ast/clone.ts", "default": "./dist/ast/clone.js" } diff --git a/packages/typescript/src/api/async/api.ts b/packages/typescript/src/api/async/api.ts index e1eec8d4d3b51..6c1eb480123e6 100644 --- a/packages/typescript/src/api/async/api.ts +++ b/packages/typescript/src/api/async/api.ts @@ -124,7 +124,6 @@ import type { } from "../proto.ts"; import { resolveFileName, - toCreateSnapshotRequest, validateSymbolResponse, } from "../proto.ts"; import { @@ -361,13 +360,13 @@ export class API implements FormatDiagnosticsHo private activeBuildOrchestrators: Set = new Set(); private activeSourceFileLeases: Map = new Map(); readonly printer: Printer; - readonly internal: InternalAPI; + readonly debug: DebugHandlers; constructor(options: APIOptions | LSPConnectionOptions = {}) { this.client = new Client(options); this.sourceFileCache = new SourceFileCache(); this.printer = new Printer(this.client); - this.internal = new InternalAPI(this.client, () => this.ensureInitialized()); // @sync: this.internal = new InternalAPI(this.client, this.ensureInitialized); + this.debug = new DebugHandlers(this.client, () => this.ensureInitialized()); // @sync: this.debug = new DebugHandlers(this.client, this.ensureInitialized); } /** @@ -482,6 +481,7 @@ export class API implements FormatDiagnosticsHo return "\n"; } + /** @internal */ async createBuildOrchestrator(rootNames: readonly string[], buildOrchestratorOptions: BuildOrchestratorOptions): Promise { await this.ensureInitialized(); const orchestratorResponse = await this.client.apiRequest("createBuildOrchestrator", { @@ -626,7 +626,7 @@ export class API implements FormatDiagnosticsHo async createSnapshot(params?: CreateSnapshotParams): Promise { await this.ensureInitialized(); - const requestParams = toCreateSnapshotRequest(this.prepareCreateSnapshotParams(params)); + const requestParams = this.prepareCreateSnapshotParams(params); const data = await this.client.apiRequest("createSnapshot", requestParams); const snapshot = new Snapshot( @@ -653,7 +653,7 @@ export class API implements FormatDiagnosticsHo const data = await this.client.apiRequest("updateSnapshot", { snapshot: baseSnapshot.id, - changes: toCreateSnapshotRequest(this.prepareCreateSnapshotParams(params)), + changes: this.prepareCreateSnapshotParams(params), }); if (data.snapshot === baseSnapshot.id) { await this.client.apiRequest("release", { snapshot: data.snapshot }); @@ -675,8 +675,8 @@ export class API implements FormatDiagnosticsHo return snapshot; } - private prepareCreateSnapshotParams(params: CreateSnapshotParams | undefined): ProtocolCreateSnapshotParams | undefined { - if (!params) return undefined; + private prepareCreateSnapshotParams(params: CreateSnapshotParams | undefined): ProtocolCreateSnapshotParams { + params ??= {}; const prepareOptions = (options: CreateProgramOptions | undefined): ProtocolCreateProgramOptions | undefined => { if (!options) return undefined; const { moduleResolver, projectReferences, ...rest } = options; @@ -884,8 +884,13 @@ function sourceFileDescriptor(sourceFile: RemoteSourceFile): SourceFileDescripto }; } +/** Returns whether a node is backed by a remote compiler response. */ +export function isRemoteNode(node: Node): boolean { + return node instanceof RemoteNode; +} + function getRemoteSourceFile(node: Node): RemoteSourceFile | undefined { - if (!(node instanceof RemoteNode)) return undefined; + if (!isRemoteNode(node)) return undefined; const file = node.getSourceFile(); return file instanceof RemoteSourceFile && file.api ? file : undefined; } @@ -951,11 +956,10 @@ export class RetainedSourceFile { } } -export class InternalAPI { +export class DebugHandlers { private client: Client; private ensureInitialized: EnsureInitialized; - /** @internal */ constructor(client: Client, ensureInitialized: EnsureInitialized) { this.client = client; this.ensureInitialized = ensureInitialized; @@ -1051,7 +1055,6 @@ export class Snapshot { private snapshotRegistry: SnapshotObjectRegistry; private projectDataMap: Map; private updateSnapshot: SnapshotUpdater; - readonly internal: SnapshotInternalAPI; private get client(): Client { return this.api.client; @@ -1083,8 +1086,6 @@ export class Snapshot { createdPrograms: data.operation.createdPrograms?.map(projectId => this.requireProject(projectId).program), openedFiles: data.operation.openedFiles?.map(result => ({ project: this.requireProject(result.project) })), }; - - this.internal = new SnapshotInternalAPI(this.id, api.client); } getProjects(): readonly Project[] { @@ -1538,15 +1539,10 @@ export class Project { readonly currentDirectory: RootedDirectoryPath; readonly dirty: boolean; readonly parsedCommandLine: ParsedCommandLine; - /** @deprecated Use `parsedCommandLine.options`. */ - readonly compilerOptions: CompilerOptions; - /** @deprecated Use `parsedCommandLine.fileNames`. */ - readonly rootFiles: readonly RootedFilePath[]; readonly program: Program; readonly checker: Checker; readonly languageService: LanguageService; - private snapshotId: number; constructor(data: ProjectResponse, snapshotId: number, toPath: (fileName: string, basePath?: string) => PathKey, api: API, snapshotRegistry: SnapshotObjectRegistry) { this.id = data.id as Id; @@ -1558,25 +1554,12 @@ export class Project { throw new Error(`Project '${data.configFileName}' has no parsed command line`); } this.parsedCommandLine = data.parsedCommandLine; - this.compilerOptions = this.parsedCommandLine.options; - this.rootFiles = this.parsedCommandLine.fileNames; - this.snapshotId = snapshotId; this.program = new Program(snapshotId, this, toPath); const objectRegistry = new ProjectObjectRegistry(snapshotId, this, snapshotRegistry); this.checker = new Checker(snapshotId, this, objectRegistry); this.languageService = new LanguageService(snapshotId, this, objectRegistry); } - /** @deprecated Use `languageService.getImportAdderEdits`. */ - getImportAdderEdits(file: DocumentIdentifier, actions: readonly APIImportAdderAction[]): Promise { - return this.languageService.getImportAdderEdits(file, actions); - } - - /** @deprecated Use `languageService.getImportEditsForSymbols`. */ - getImportEditsForSymbols(file: DocumentIdentifier, symbols: readonly Symbol[], options: GetImportEditsForSymbolsOptions = {}): Promise { - return this.languageService.getImportEditsForSymbols(file, symbols, options); - } - dispose(): void { this.checker.dispose(); } @@ -1686,6 +1669,27 @@ export class LanguageService { })), }; } + + /** + * Format a synthesized node with the correct indentation for insertion at a + * specific position in an existing source file. + * + * @param node The synthesized AST node to format. + * @param file The target file where the node will be inserted. + * @param position The UTF-16 code-unit offset in the target file for insertion. + * @returns The formatted text of the node, indented for the insertion position. + */ + async formatNodeForInsertion(node: Node, file: DocumentIdentifier, position: number): Promise { + const encoded = encodeNode(node); + const base64 = uint8ArrayToBase64(encoded); + return this.client.apiRequest("formatNodeForInsertion", { + snapshot: this.snapshotId, + project: this.project.id, + file, + position, + data: base64, + }); + } } export class Program implements FormatDiagnosticsHost { @@ -1723,7 +1727,7 @@ export class Program implements FormatDiagnost } getNewLine(): string { - return this.project.compilerOptions.newLine === NewLineKind.CRLF ? "\r\n" : "\n"; + return this.project.parsedCommandLine.options.newLine === NewLineKind.CRLF ? "\r\n" : "\n"; } /** @internal */ @@ -1746,7 +1750,7 @@ export class Program implements FormatDiagnost } getCompilerOptions(): CompilerOptions { - return this.project.compilerOptions; + return this.project.parsedCommandLine.options; } async getSourceFile(file: DocumentIdentifier): Promise { @@ -1757,8 +1761,6 @@ export class Program implements FormatDiagnost /** * Returns the source file for an already-canonical path. - * - * @internal */ getSourceFileByPath(path: PathKey): Promise { // The wire format is a string, but the cache key remains the supplied @@ -2438,21 +2440,6 @@ export class Checker { return (data ?? []).map(h => new NodeHandle(h, this.project)); } - /** @deprecated Use `project.languageService.getReferencedSymbolsForNode`. */ - getReferencedSymbolsForNode(node: Node, position: number): Promise { - return this.project.languageService.getReferencedSymbolsForNode(node, position); - } - - /** @deprecated Use `project.languageService.getSignatureUsage`. */ - getSignatureUsage(signatureDecl: Node): Promise { - return this.project.languageService.getSignatureUsage(signatureDecl); - } - - /** @deprecated Use `project.languageService.getCompletionsAtPosition`. */ - getCompletionsAtPosition(document: string, position: number, options?: CompletionOptions): Promise { - return this.project.languageService.getCompletionsAtPosition(document, position, options); - } - /** * Get the type at a node location. Always returns a type; for nodes whose * type cannot be determined the checker yields the error type (use @@ -3164,45 +3151,6 @@ export class Printer { } } -export class SnapshotInternalAPI { - private snapshotId: number; - private client: Client; - - constructor(snapshotId: number, client: Client) { - this.snapshotId = snapshotId; - this.client = client; - } - - /** - * Format a synthesized node with the correct indentation for insertion at a - * specific position in an existing source file. - * - * @param node The synthesized AST node to format. - * @param file The target file where the node will be inserted. - * @param position The UTF-16 code-unit offset in the target file for insertion. - * @returns The formatted text of the node, indented for the insertion position. - */ - async formatNodeForInsertion(node: Node, file: DocumentIdentifier, position: number): Promise { - const data = await this.client.apiRequest("getDefaultProjectForFile", { - snapshot: this.snapshotId, - file, - }); - if (!data) { - throw new Error(`No project found for file: ${typeof file === "string" ? file : file.uri}`); - } - - const encoded = encodeNode(node); - const base64 = uint8ArrayToBase64(encoded); - return this.client.apiRequest("formatNodeForInsertion", { - snapshot: this.snapshotId, - project: data.id, - file, - position, - data: base64, - }); - } -} - export class NodeHandle { /** * The project this handle was produced in, used as the default for {@link resolve}. diff --git a/packages/typescript/src/api/node/node.ts b/packages/typescript/src/api/node/node.ts index 99e2a1ed991bf..bca2153328903 100644 --- a/packages/typescript/src/api/node/node.ts +++ b/packages/typescript/src/api/node/node.ts @@ -196,7 +196,6 @@ export class RemoteSourceFile extends RemoteNode implements SourceFileInfo { return result; } - /** @internal */ getOrCreateNodeAtIndex(index: number): Node { let node = this.nodes[index]; if (!node) { diff --git a/packages/typescript/src/api/proto.generated.ts b/packages/typescript/src/api/proto.generated.ts index 8d8489615ec6a..01e2fa27b12c2 100644 --- a/packages/typescript/src/api/proto.generated.ts +++ b/packages/typescript/src/api/proto.generated.ts @@ -184,6 +184,7 @@ export interface APIMethodInfo { getReferencedSymbolsForNode: APIMethod; getSignatureUsages: APIMethod; getCompletionsAtPosition: APIMethod; + formatNodeForInsertion: APIMethod; getSyntacticDiagnostics: APIMethod; getBindDiagnostics: APIMethod; getSemanticDiagnostics: APIMethod; @@ -193,7 +194,6 @@ export interface APIMethodInfo { getGlobalDiagnostics: APIMethod; getConfigFileParsingDiagnostics: APIMethod; printNode: APIMethod; - formatNodeForInsertion: APIMethod; emit: APIMethod; emitToString: APIMethod; getJavaScriptEmit: APIMethod; @@ -471,10 +471,6 @@ export interface ProjectResponse { currentDirectory: RootedDirectoryPath; dirty: boolean; parsedCommandLine: ConfigFileResponse; - /** @deprecated Use parsedCommandLine.fileNames. */ - rootFiles: RootedFilePath[]; - /** @deprecated Use parsedCommandLine.options. */ - compilerOptions: CompilerOptions; } export interface GetSymbolAtPositionParams { @@ -1002,6 +998,18 @@ export interface CompletionInfoResponse { entries: CompletionEntryResponse[]; } +/** FormatNodeForInsertionParams are the parameters for the formatNodeForInsertion method. */ +export interface FormatNodeForInsertionParams { + snapshot: number; + project: ProjectId; + /** target file where the node will be inserted */ + file: DocumentIdentifier; + /** UTF-16 code-unit offset of the insertion position in the target file */ + position: number; + /** base64-encoded binary AST data for the synthesized node */ + data: string; +} + /** GetDiagnosticsParams are parameters for per-file diagnostic methods. */ export interface GetDiagnosticsParams { snapshot: number; @@ -1050,18 +1058,6 @@ export interface PrintNodeParams { terminateUnterminatedLiterals?: boolean | undefined; } -/** FormatNodeForInsertionParams are the parameters for the formatNodeForInsertion method. */ -export interface FormatNodeForInsertionParams { - snapshot: number; - project: ProjectId; - /** target file where the node will be inserted */ - file: DocumentIdentifier; - /** UTF-16 code-unit offset of the insertion position in the target file */ - position: number; - /** base64-encoded binary AST data for the synthesized node */ - data: string; -} - export interface EmitParams { snapshot: number; project: ProjectId; diff --git a/packages/typescript/src/api/proto.ts b/packages/typescript/src/api/proto.ts index 2651e5a2e0d0d..1cf9a8a7ab83b 100644 --- a/packages/typescript/src/api/proto.ts +++ b/packages/typescript/src/api/proto.ts @@ -128,33 +128,8 @@ export function resolveDocumentURI(identifier: DocumentIdentifier): string { return identifier.uri; } -/** - * Parameters for createSnapshot, including deprecated members handled by `toCreateSnapshotRequest` - */ -export interface CreateSnapshotParams extends CoreCreateSnapshotParams { - /** - * @deprecated Use {@link openProjects} instead. - * Path to a tsconfig.json file to open in the new snapshot. - */ - openProject?: string | undefined; -} +export type CreateSnapshotParams = CoreCreateSnapshotParams; export interface CreateBuildOrchestratorParams { rootNames: readonly string[] | null; } - -/** - * Builds the wire request for createSnapshot, applying the deprecated `openProject` - * compatibility shim: a single `openProject` is folded into `openProjects` and is - * never sent on the wire. - */ -export function toCreateSnapshotRequest(params?: CreateSnapshotParams): CreateSnapshotParams { - const { openProject, openProjects, ...rest } = params ?? {}; - const mergedOpenProjects = openProject !== undefined - ? [resolveFileName(openProject), ...(openProjects ?? [])] - : openProjects; - return { - ...rest, - openProjects: mergedOpenProjects, - }; -} diff --git a/packages/typescript/src/api/sync/api.ts b/packages/typescript/src/api/sync/api.ts index f8976dcbb6793..a2960224381ff 100644 --- a/packages/typescript/src/api/sync/api.ts +++ b/packages/typescript/src/api/sync/api.ts @@ -141,7 +141,6 @@ import type { } from "../proto.ts"; import { resolveFileName, - toCreateSnapshotRequest, validateSymbolResponse, } from "../proto.ts"; import { @@ -380,13 +379,13 @@ export class API implements FormatDiagnosticsHo private activeBuildOrchestrators: Set = new Set(); private activeSourceFileLeases: Map = new Map(); readonly printer: Printer; - readonly internal: InternalAPI; + readonly debug: DebugHandlers; constructor(options: APIOptions | LSPConnectionOptions = {}) { this.client = new Client(options); this.sourceFileCache = new SourceFileCache(); this.printer = new Printer(this.client); - this.internal = new InternalAPI(this.client, this.ensureInitialized); + this.debug = new DebugHandlers(this.client, this.ensureInitialized); } /** @@ -581,6 +580,7 @@ export class API implements FormatDiagnosticsHo return "\n"; } + /** @internal */ get createBuildOrchestrator(): { (rootNames: readonly string[], buildOrchestratorOptions: BuildOrchestratorOptions): BuildOrchestrator; gen(rootNames: readonly string[], buildOrchestratorOptions: BuildOrchestratorOptions): Generator; @@ -936,7 +936,7 @@ export class API implements FormatDiagnosticsHo function createSnapshot(params?: CreateSnapshotParams): Snapshot { owner.ensureInitialized(); - const requestParams = toCreateSnapshotRequest(owner.prepareCreateSnapshotParams(params)); + const requestParams = owner.prepareCreateSnapshotParams(params); const data = owner.client.apiRequest("createSnapshot", requestParams); const snapshot = new Snapshot( @@ -959,7 +959,7 @@ export class API implements FormatDiagnosticsHo function* gen(params?: CreateSnapshotParams): Generator { yield* owner.ensureInitialized.gen(); - const requestParams = toCreateSnapshotRequest(owner.prepareCreateSnapshotParams(params)); + const requestParams = owner.prepareCreateSnapshotParams(params); const data = yield* apiRequest("createSnapshot", requestParams); const snapshot = new Snapshot( @@ -996,7 +996,7 @@ export class API implements FormatDiagnosticsHo const data = owner.client.apiRequest("updateSnapshot", { snapshot: baseSnapshot.id, - changes: toCreateSnapshotRequest(owner.prepareCreateSnapshotParams(params)), + changes: owner.prepareCreateSnapshotParams(params), }); if (data.snapshot === baseSnapshot.id) { owner.client.apiRequest("release", { snapshot: data.snapshot }); @@ -1025,7 +1025,7 @@ export class API implements FormatDiagnosticsHo const data = yield* apiRequest("updateSnapshot", { snapshot: baseSnapshot.id, - changes: toCreateSnapshotRequest(owner.prepareCreateSnapshotParams(params)), + changes: owner.prepareCreateSnapshotParams(params), }); if (data.snapshot === baseSnapshot.id) { yield* apiRequest("release", { snapshot: data.snapshot }); @@ -1049,8 +1049,8 @@ export class API implements FormatDiagnosticsHo ); } - private prepareCreateSnapshotParams(params: CreateSnapshotParams | undefined): ProtocolCreateSnapshotParams | undefined { - if (!params) return undefined; + private prepareCreateSnapshotParams(params: CreateSnapshotParams | undefined): ProtocolCreateSnapshotParams { + params ??= {}; const prepareOptions = (options: CreateProgramOptions | undefined): ProtocolCreateProgramOptions | undefined => { if (!options) return undefined; const { moduleResolver, projectReferences, ...rest } = options; @@ -1435,8 +1435,13 @@ function sourceFileDescriptor(sourceFile: RemoteSourceFile): SourceFileDescripto }; } +/** Returns whether a node is backed by a remote compiler response. */ +export function isRemoteNode(node: Node): boolean { + return node instanceof RemoteNode; +} + function getRemoteSourceFile(node: Node): RemoteSourceFile | undefined { - if (!(node instanceof RemoteNode)) return undefined; + if (!isRemoteNode(node)) return undefined; const file = node.getSourceFile(); return file instanceof RemoteSourceFile && file.api ? file : undefined; } @@ -1535,11 +1540,10 @@ export class RetainedSourceFile { } } -export class InternalAPI { +export class DebugHandlers { private client: Client; private ensureInitialized: EnsureInitialized; - /** @internal */ constructor(client: Client, ensureInitialized: EnsureInitialized) { this.client = client; this.ensureInitialized = ensureInitialized; @@ -1679,7 +1683,6 @@ export class Snapshot { private snapshotRegistry: SnapshotObjectRegistry; private projectDataMap: Map; private updateSnapshot: SnapshotUpdater; - readonly internal: SnapshotInternalAPI; private get client(): Client { return this.api.client; @@ -1711,8 +1714,6 @@ export class Snapshot { createdPrograms: data.operation.createdPrograms?.map(projectId => this.requireProject(projectId).program), openedFiles: data.operation.openedFiles?.map(result => ({ project: this.requireProject(result.project) })), }; - - this.internal = new SnapshotInternalAPI(this.id, api.client); } getProjects(): readonly Project[] { @@ -2569,15 +2570,10 @@ export class Project { readonly currentDirectory: RootedDirectoryPath; readonly dirty: boolean; readonly parsedCommandLine: ParsedCommandLine; - /** @deprecated Use `parsedCommandLine.options`. */ - readonly compilerOptions: CompilerOptions; - /** @deprecated Use `parsedCommandLine.fileNames`. */ - readonly rootFiles: readonly RootedFilePath[]; readonly program: Program; readonly checker: Checker; readonly languageService: LanguageService; - private snapshotId: number; constructor(data: ProjectResponse, snapshotId: number, toPath: (fileName: string, basePath?: string) => PathKey, api: API, snapshotRegistry: SnapshotObjectRegistry) { this.id = data.id as Id; @@ -2589,51 +2585,12 @@ export class Project { throw new Error(`Project '${data.configFileName}' has no parsed command line`); } this.parsedCommandLine = data.parsedCommandLine; - this.compilerOptions = this.parsedCommandLine.options; - this.rootFiles = this.parsedCommandLine.fileNames; - this.snapshotId = snapshotId; this.program = new Program(snapshotId, this, toPath); const objectRegistry = new ProjectObjectRegistry(snapshotId, this, snapshotRegistry); this.checker = new Checker(snapshotId, this, objectRegistry); this.languageService = new LanguageService(snapshotId, this, objectRegistry); } - /** @deprecated Use `languageService.getImportAdderEdits`. */ - get getImportAdderEdits(): { - (file: DocumentIdentifier, actions: readonly APIImportAdderAction[]): readonly TextEdit[]; - gen(file: DocumentIdentifier, actions: readonly APIImportAdderAction[]): Generator; - } { - const owner = this; - return cacheGeneratorMethod( - owner, - "getImportAdderEdits", - function (file: DocumentIdentifier, actions: readonly APIImportAdderAction[]): readonly TextEdit[] { - return owner.languageService.getImportAdderEdits(file, actions); - }, - function* (file: DocumentIdentifier, actions: readonly APIImportAdderAction[]): Generator { - return yield* owner.languageService.getImportAdderEdits.gen(file, actions); - }, - ); - } - - /** @deprecated Use `languageService.getImportEditsForSymbols`. */ - get getImportEditsForSymbols(): { - (file: DocumentIdentifier, symbols: readonly Symbol[], options?: GetImportEditsForSymbolsOptions): readonly TextEdit[]; - gen(file: DocumentIdentifier, symbols: readonly Symbol[], options?: GetImportEditsForSymbolsOptions): Generator; - } { - const owner = this; - return cacheGeneratorMethod( - owner, - "getImportEditsForSymbols", - function (file: DocumentIdentifier, symbols: readonly Symbol[], options: GetImportEditsForSymbolsOptions = {}): readonly TextEdit[] { - return owner.languageService.getImportEditsForSymbols(file, symbols, options); - }, - function* (file: DocumentIdentifier, symbols: readonly Symbol[], options: GetImportEditsForSymbolsOptions = {}): Generator { - return yield* owner.languageService.getImportEditsForSymbols.gen(file, symbols, options); - }, - ); - } - dispose(): void { this.checker.dispose(); } @@ -2878,6 +2835,48 @@ export class LanguageService { }, ); } + + /** + * Format a synthesized node with the correct indentation for insertion at a + * specific position in an existing source file. + * + * @param node The synthesized AST node to format. + * @param file The target file where the node will be inserted. + * @param position The UTF-16 code-unit offset in the target file for insertion. + * @returns The formatted text of the node, indented for the insertion position. + */ + get formatNodeForInsertion(): { + (node: Node, file: DocumentIdentifier, position: number): string; + gen(node: Node, file: DocumentIdentifier, position: number): Generator; + } { + const owner = this; + return cacheGeneratorMethod( + owner, + "formatNodeForInsertion", + function (node: Node, file: DocumentIdentifier, position: number): string { + const encoded = encodeNode(node); + const base64 = uint8ArrayToBase64(encoded); + return owner.client.apiRequest("formatNodeForInsertion", { + snapshot: owner.snapshotId, + project: owner.project.id, + file, + position, + data: base64, + }); + }, + function* (node: Node, file: DocumentIdentifier, position: number): Generator { + const encoded = encodeNode(node); + const base64 = uint8ArrayToBase64(encoded); + return yield* apiRequest("formatNodeForInsertion", { + snapshot: owner.snapshotId, + project: owner.project.id, + file, + position, + data: base64, + }); + }, + ); + } } export class Program implements FormatDiagnosticsHost { @@ -2915,7 +2914,7 @@ export class Program implements FormatDiagnost } getNewLine(): string { - return this.project.compilerOptions.newLine === NewLineKind.CRLF ? "\r\n" : "\n"; + return this.project.parsedCommandLine.options.newLine === NewLineKind.CRLF ? "\r\n" : "\n"; } /** @internal */ @@ -2966,7 +2965,7 @@ export class Program implements FormatDiagnost } getCompilerOptions(): CompilerOptions { - return this.project.compilerOptions; + return this.project.parsedCommandLine.options; } get getSourceFile(): { @@ -2992,8 +2991,6 @@ export class Program implements FormatDiagnost /** * Returns the source file for an already-canonical path. - * - * @internal */ get getSourceFileByPath(): { (path: PathKey): SourceFile | undefined; @@ -4543,60 +4540,6 @@ export class Checker { ); } - /** @deprecated Use `project.languageService.getReferencedSymbolsForNode`. */ - get getReferencedSymbolsForNode(): { - (node: Node, position: number): ReferencedSymbolEntry[]; - gen(node: Node, position: number): Generator; - } { - const owner = this; - return cacheGeneratorMethod( - owner, - "getReferencedSymbolsForNode", - function (node: Node, position: number): ReferencedSymbolEntry[] { - return owner.project.languageService.getReferencedSymbolsForNode(node, position); - }, - function* (node: Node, position: number): Generator { - return yield* owner.project.languageService.getReferencedSymbolsForNode.gen(node, position); - }, - ); - } - - /** @deprecated Use `project.languageService.getSignatureUsage`. */ - get getSignatureUsage(): { - (signatureDecl: Node): SignatureUsage[]; - gen(signatureDecl: Node): Generator; - } { - const owner = this; - return cacheGeneratorMethod( - owner, - "getSignatureUsage", - function (signatureDecl: Node): SignatureUsage[] { - return owner.project.languageService.getSignatureUsage(signatureDecl); - }, - function* (signatureDecl: Node): Generator { - return yield* owner.project.languageService.getSignatureUsage.gen(signatureDecl); - }, - ); - } - - /** @deprecated Use `project.languageService.getCompletionsAtPosition`. */ - get getCompletionsAtPosition(): { - (document: string, position: number, options?: CompletionOptions): CompletionInfo | undefined; - gen(document: string, position: number, options?: CompletionOptions): Generator; - } { - const owner = this; - return cacheGeneratorMethod( - owner, - "getCompletionsAtPosition", - function (document: string, position: number, options?: CompletionOptions): CompletionInfo | undefined { - return owner.project.languageService.getCompletionsAtPosition(document, position, options); - }, - function* (document: string, position: number, options?: CompletionOptions): Generator { - return yield* owner.project.languageService.getCompletionsAtPosition.gen(document, position, options); - }, - ); - } - /** * Get the type at a node location. Always returns a type; for nodes whose * type cannot be determined the checker yields the error type (use @@ -6595,74 +6538,6 @@ export class Printer { } } -export class SnapshotInternalAPI { - private snapshotId: number; - private client: Client; - - constructor(snapshotId: number, client: Client) { - this.snapshotId = snapshotId; - this.client = client; - } - - /** - * Format a synthesized node with the correct indentation for insertion at a - * specific position in an existing source file. - * - * @param node The synthesized AST node to format. - * @param file The target file where the node will be inserted. - * @param position The UTF-16 code-unit offset in the target file for insertion. - * @returns The formatted text of the node, indented for the insertion position. - */ - get formatNodeForInsertion(): { - (node: Node, file: DocumentIdentifier, position: number): string; - gen(node: Node, file: DocumentIdentifier, position: number): Generator; - } { - const owner = this; - return cacheGeneratorMethod( - owner, - "formatNodeForInsertion", - function (node: Node, file: DocumentIdentifier, position: number): string { - const data = owner.client.apiRequest("getDefaultProjectForFile", { - snapshot: owner.snapshotId, - file, - }); - if (!data) { - throw new Error(`No project found for file: ${typeof file === "string" ? file : file.uri}`); - } - - const encoded = encodeNode(node); - const base64 = uint8ArrayToBase64(encoded); - return owner.client.apiRequest("formatNodeForInsertion", { - snapshot: owner.snapshotId, - project: data.id, - file, - position, - data: base64, - }); - }, - function* (node: Node, file: DocumentIdentifier, position: number): Generator { - const data = yield* apiRequest("getDefaultProjectForFile", { - snapshot: owner.snapshotId, - file, - }); - if (!data) { - throw new Error(`No project found for file: ${typeof file === "string" ? file : file.uri}`); - } - - const encoded = encodeNode(node); - const base64 = uint8ArrayToBase64(encoded); - return yield* apiRequest("formatNodeForInsertion", { - snapshot: owner.snapshotId, - project: data.id, - file, - position, - data: base64, - }); - }, - ); - } -} - export class NodeHandle { /** * The project this handle was produced in, used as the default for {@link resolve}. diff --git a/packages/typescript/src/ast/ast.ts b/packages/typescript/src/ast/ast.ts index 058a67de9165a..9f644c12fd0c1 100644 --- a/packages/typescript/src/ast/ast.ts +++ b/packages/typescript/src/ast/ast.ts @@ -56,6 +56,7 @@ export { SyntaxKind } from "#enums/syntaxKind"; export { TokenFlags } from "#enums/tokenFlags"; export * from "./ast.generated.ts"; +export * as factory from "./factory.generated.ts"; // ── Core types ── diff --git a/packages/typescript/src/ast/factory.generated.ts b/packages/typescript/src/ast/factory.generated.ts index 7a7a19b78457c..ac1ac5f377266 100644 --- a/packages/typescript/src/ast/factory.generated.ts +++ b/packages/typescript/src/ast/factory.generated.ts @@ -273,6 +273,7 @@ import { yieldEachChildOfJSDocPropertyTag, } from "./visitor.ts"; +/** @internal */ export class NodeObject { readonly kind: SyntaxKind; flags: NodeFlags = 0 as NodeFlags; diff --git a/packages/typescript/src/vscode/extensionApi.ts b/packages/typescript/src/vscode/extensionApi.ts index 4f947490805aa..be668195f9af9 100644 --- a/packages/typescript/src/vscode/extensionApi.ts +++ b/packages/typescript/src/vscode/extensionApi.ts @@ -48,18 +48,18 @@ export type LspMiddlewareTransformer = ( ) => LspMiddlewareResult | PromiseLike>; export interface APIModules { - "typescript/unstable/async": typeof import("../api/async/api.ts"); - "typescript/unstable/sync": typeof import("../api/sync/api.ts"); - "typescript/unstable/fs": typeof import("../api/fs.ts"); - "typescript/unstable/path": typeof import("../api/typedPaths.ts"); - "typescript/unstable/proto": typeof import("../api/proto.ts"); - "typescript/unstable/ast": typeof import("../ast/index.ts"); - "typescript/unstable/ast/is": typeof import("../ast/is.ts"); - "typescript/unstable/ast/factory": typeof import("../ast/factory.generated.ts"); - "typescript/unstable/ast/utils": typeof import("../ast/utils.ts"); - "typescript/unstable/ast/scanner": typeof import("../ast/scanner.ts"); - "typescript/unstable/ast/visitor": typeof import("../ast/visitor.ts"); - "typescript/unstable/ast/clone": typeof import("../ast/clone.ts"); + "typescript/async": typeof import("../api/async/api.ts"); + "typescript/sync": typeof import("../api/sync/api.ts"); + "typescript/fs": typeof import("../api/fs.ts"); + "typescript/path": typeof import("../api/typedPaths.ts"); + "typescript/proto": typeof import("../api/proto.ts"); + "typescript/ast": typeof import("../ast/index.ts"); + "typescript/ast/is": typeof import("../ast/is.ts"); + "typescript/ast/factory": typeof import("../ast/factory.generated.ts"); + "typescript/ast/utils": typeof import("../ast/utils.ts"); + "typescript/ast/scanner": typeof import("../ast/scanner.ts"); + "typescript/ast/visitor": typeof import("../ast/visitor.ts"); + "typescript/ast/clone": typeof import("../ast/clone.ts"); [exportPath: string]: unknown; } diff --git a/packages/typescript/test/api-comparison.bench.ts b/packages/typescript/test/api-comparison.bench.ts index e515cb383ee14..2a79b8906e169 100644 --- a/packages/typescript/test/api-comparison.bench.ts +++ b/packages/typescript/test/api-comparison.bench.ts @@ -1,13 +1,13 @@ import { API as AsyncAPI, type Project as AsyncProject, -} from "@typescript/typescript/unstable/async"; +} from "@typescript/typescript/async"; import { all, API as SyncAPI, defer, type Project as SyncProject, -} from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/sync"; import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; @@ -357,7 +357,7 @@ export async function runBenchmarks(options?: { filter?: string; singleIteration function createSyncContext(): SyncContext { const api = new SyncAPI({ cwd: repoRoot }); - const snapshot = api.createSnapshot({ openProject: "tsc/testdata/fixtures/compiler/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["tsc/testdata/fixtures/compiler/tsconfig.json"] }); const project = snapshot.getProjects()[0]; project.checker.getSymbolAtPosition("core.ts", 0); return { api, project }; @@ -365,7 +365,7 @@ export async function runBenchmarks(options?: { filter?: string; singleIteration async function createAsyncContext(): Promise { const api = new AsyncAPI({ cwd: repoRoot }); - const snapshot = await api.createSnapshot({ openProject: "tsc/testdata/fixtures/compiler/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["tsc/testdata/fixtures/compiler/tsconfig.json"] }); const project = snapshot.getProjects()[0]; await project.checker.getSymbolAtPosition("core.ts", 0); return { api, project }; @@ -373,7 +373,7 @@ export async function runBenchmarks(options?: { filter?: string; singleIteration function createGeneratorContext(): SyncContext { const api = new SyncAPI({ cwd: repoRoot }); - const [snapshot] = api.batch(api.createSnapshot.gen({ openProject: "tsc/testdata/fixtures/compiler/tsconfig.json" })); + const [snapshot] = api.batch(api.createSnapshot.gen({ openProjects: ["tsc/testdata/fixtures/compiler/tsconfig.json"] })); const project = snapshot.getProjects()[0]; api.batch(project.checker.getSymbolAtPosition.gen("core.ts", 0)); return { api, project }; diff --git a/packages/typescript/test/async/api.bench.ts b/packages/typescript/test/async/api.bench.ts index 01196f4cece46..5ea8d1d0783f9 100644 --- a/packages/typescript/test/async/api.bench.ts +++ b/packages/typescript/test/async/api.bench.ts @@ -2,12 +2,12 @@ import { type Node, type SourceFile, SyntaxKind, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { API, type Project, type Snapshot, -} from "@typescript/typescript/unstable/async"; // @sync: } from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/async"; // @sync: } from "@typescript/typescript/sync"; import { writeFileSync } from "node:fs"; import inspector from "node:inspector"; import path from "node:path"; @@ -206,7 +206,7 @@ export async function runBenchmarks(options?: { filter?: string; singleIteration } async function loadSnapshot() { - snapshot = await api.createSnapshot({ openProject: "tsc/testdata/fixtures/compiler/tsconfig.json" }); // @generators: [snapshot] = api.batch(api.createSnapshot.gen({ openProject: "tsc/testdata/fixtures/compiler/tsconfig.json" })); + snapshot = await api.createSnapshot({ openProjects: ["tsc/testdata/fixtures/compiler/tsconfig.json"] }); // @generators: [snapshot] = api.batch(api.createSnapshot.gen({ openProjects: ["tsc/testdata/fixtures/compiler/tsconfig.json" ]})); project = snapshot.getProjects()[0]; } diff --git a/packages/typescript/test/async/api.test.ts b/packages/typescript/test/async/api.test.ts index f9245bdb4d216..b9ef5842d4489 100644 --- a/packages/typescript/test/async/api.test.ts +++ b/packages/typescript/test/async/api.test.ts @@ -41,7 +41,7 @@ import { SyntaxKind, tryGetAmbientModuleNameFromSymbolName, unescapeLeadingUnderscores, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { cloneNode, createArrayTypeNode, @@ -58,8 +58,8 @@ import { createVariableDeclaration, createVariableDeclarationList, createVariableStatement, -} from "@typescript/typescript/unstable/ast/factory"; -import { visitEachChild } from "@typescript/typescript/unstable/ast/visitor"; +} from "@typescript/typescript/ast/factory"; +import { visitEachChild } from "@typescript/typescript/ast/visitor"; import { API, type BigIntLiteralType, @@ -111,20 +111,20 @@ import { type TypeReference, type UnionOrIntersectionType, type UserPreferences, -} from "@typescript/typescript/unstable/async"; // @sync: } from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/async"; // @sync: } from "@typescript/typescript/sync"; import { createFileSystem, createFileSystemLayer, createFileSystemWithLib, type FileSystemCallbacks, serverFS, -} from "@typescript/typescript/unstable/fs"; +} from "@typescript/typescript/fs"; import { rootedDirectoryPathFromPath, rootedFilePathFromPath, toRootedDirectoryPath, toRootedFilePath, -} from "@typescript/typescript/unstable/path"; +} from "@typescript/typescript/path"; import assert from "node:assert"; import { globSync } from "node:fs"; import { resolve } from "node:path"; @@ -589,6 +589,7 @@ describe("API", { concurrency }, () => { const symbol = await request; assert.ok(symbol); assert.strictEqual(cache.symbolsByDeclarationNodeIndex.get(index), symbol); + // @ts-ignore -- Internal symbol identity is exercised by source tests. assert.strictEqual(cache.symbolsById.get(symbol.reference.id), symbol); assert.equal(cache.declarationSymbolRequests.has(index), false); api.clearSourceFileCache(); @@ -752,7 +753,7 @@ describe("API", { concurrency }, () => { ], }); assert.equal(snapshot.getProjects().length, 2); - assert.deepEqual(snapshot.getProjects().map(project => project.rootFiles), [["/src/a.ts"], ["/src/b.ts"]]); + assert.deepEqual(snapshot.getProjects().map(project => project.parsedCommandLine.fileNames), [["/src/a.ts"], ["/src/b.ts"]]); assert.equal(snapshot.operation.createdPrograms!.length, 2); for (const program of snapshot.operation.createdPrograms!) { const syntheticProjectId: SyntheticProjectId = program.id; @@ -1572,7 +1573,7 @@ describe("API - batchContext", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("value:")); assert.ok(symbol); @@ -1617,6 +1618,7 @@ describe("BuildOrchestrator", () => { const { api: disposableApi } = spawnAPIWithFS({ ...files }); await using api = disposableApi; const options = await api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. await using orchestrator = await api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/", ...options }, @@ -1634,10 +1636,12 @@ describe("BuildOrchestrator", () => { test("api.close disposes all build orchestrators", async () => { const { api } = spawnAPIWithFS({ ...files }); const options = await api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator1 = await api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/", ...options }, ); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator2 = await api.createBuildOrchestrator( ["/b/tsconfig.json"], { cwd: "/", ...options }, @@ -1671,6 +1675,7 @@ describe("BuildOrchestrator", () => { traceResolution: false, }, }; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/a/tsconfig.json", "/b/tsconfig.json"], defaultOptions, @@ -1691,6 +1696,7 @@ describe("BuildOrchestrator", () => { "/a/src/index.ts": source, }); await using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/" }, @@ -1717,6 +1723,7 @@ describe("BuildOrchestrator", () => { const { api: disposableApi } = spawnAPIWithFS({ ...files }); await using api = disposableApi; const options = await api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/", ...options }, @@ -1787,6 +1794,7 @@ describe("BuildOrchestrator", () => { "/a/dist/index.js": `export const a = 1;`, }); await using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/" }, @@ -1808,6 +1816,7 @@ describe("BuildOrchestrator", () => { test("rebuilds projects after multiple file system changes", async () => { const { api: disposableApi, fs } = spawnAPIWithFS({ ...files }); await using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/a/tsconfig.json", "/b/tsconfig.json"], { cwd: "/" }, @@ -1837,6 +1846,7 @@ describe("BuildOrchestrator", () => { test("clean removes build outputs", async () => { const { api: disposableApi, fs } = spawnAPIWithFS({ ...files }); await using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1855,6 +1865,7 @@ describe("BuildOrchestrator", () => { test("builds and cleans selected projects after file system changes", async () => { const { api: disposableApi, fs } = spawnAPIWithFS({ ...files }); await using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1898,6 +1909,7 @@ describe("BuildOrchestrator", () => { }); await using api = disposableApi; const options = await api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1914,6 +1926,7 @@ describe("BuildOrchestrator", () => { ...files, }); await using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1953,6 +1966,7 @@ describe("BuildOrchestrator", () => { path => writes.push(path), ); await using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = await api.createBuildOrchestrator( ["/c/tsconfig.json", "/d/tsconfig.json"], { cwd: "/" }, @@ -1988,7 +2002,7 @@ describe("Checker - getImmediateAliasedSymbol", { concurrency }, () => { "/src/main.ts": `import { foo } from "./foo";\nexport const usage = foo;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `import { foo } from "./foo";`.indexOf("foo }"); const aliasSymbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -2016,7 +2030,7 @@ test(); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -2041,7 +2055,7 @@ describe("Snapshot", { concurrency }, () => { test("createSnapshot returns snapshot with projects", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); assert.ok(snapshot); assert.ok(snapshot.id); assert.ok(snapshot.getProjects().length > 0); @@ -2054,19 +2068,17 @@ describe("Snapshot", { concurrency }, () => { "/tsconfig.json": JSON.stringify({ compileOnSave: true }), }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; assert.deepEqual(project.parsedCommandLine.fileNames, ["/src/index.ts", "/src/foo.ts"]); assert.deepEqual(project.parsedCommandLine.options, { configFilePath: "/tsconfig.json" }); assert.equal(project.parsedCommandLine.compileOnSave, true); - assert.deepEqual(project.rootFiles, project.parsedCommandLine.fileNames); - assert.deepEqual(project.compilerOptions, project.parsedCommandLine.options); }); test("getSymbolAtPosition", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/index.ts", 9); assert.ok(symbol); @@ -2077,7 +2089,7 @@ describe("Snapshot", { concurrency }, () => { test("getSymbolAtLocation", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2095,7 +2107,7 @@ describe("Snapshot", { concurrency }, () => { test("getSymbolOfSourceFile", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const moduleSymbol = await project.checker.getSymbolOfSourceFile("/src/foo.ts"); assert.ok(moduleSymbol); @@ -2109,7 +2121,7 @@ describe("Snapshot", { concurrency }, () => { "/src/script.ts": `const x = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolOfSourceFile("/src/script.ts"); assert.equal(symbol, undefined); @@ -2118,7 +2130,7 @@ describe("Snapshot", { concurrency }, () => { test("getSymbolOfSourceFile batched", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbols = await project.checker.getSymbolOfSourceFile(["/src/index.ts", "/src/foo.ts"]); assert.equal(symbols.length, 2); @@ -2130,7 +2142,7 @@ describe("Snapshot", { concurrency }, () => { test("getTypeOfSymbol", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/index.ts", 9); assert.ok(symbol); @@ -2157,7 +2169,7 @@ describe("Snapshot", { concurrency }, () => { }); // when `"exactOptionalPropertyTypes": true` - const snapshot1 = await api.createSnapshot({ openProject: "/tsconfig-one.json" }); + const snapshot1 = await api.createSnapshot({ openProjects: ["/tsconfig-one.json"] }); const project1 = snapshot1.getConfiguredProject("/tsconfig-one.json")!; const type1 = await project1.checker.getTypeAtPosition("/src/index.ts", 7); assert.ok(type1); @@ -2174,7 +2186,7 @@ describe("Snapshot", { concurrency }, () => { assert.ok(propertyType2.flags & TypeFlags.String); // when `"exactOptionalPropertyTypes": false` - const snapshot2 = await api.createSnapshot({ openProject: "/tsconfig-two.json" }); + const snapshot2 = await api.createSnapshot({ openProjects: ["/tsconfig-two.json"] }); const project2 = snapshot2.getConfiguredProject("/tsconfig-two.json")!; const type2 = await project2.checker.getTypeAtPosition("/src/index.ts", 7); assert.ok(type2); @@ -2200,7 +2212,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `export const foo = 1;\n`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/foo.ts", "export const ".length); assert.ok(symbol); @@ -2218,7 +2230,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `export const foo = 1;\nexport const bar = 2;\n`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const foo = await project.checker.getSymbolAtPosition("/src/foo.ts", "export const ".length); const bar = await project.checker.getSymbolAtPosition("/src/foo.ts", "export const foo = 1;\nexport const ".length); @@ -2241,7 +2253,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/outside/src/foo.ts": `export const foo = 1;\n`, }); try { - const snapshot = await api.createSnapshot({ openProject: "/outside/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/outside/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/outside/tsconfig.json")!; const foo = await project.checker.getSymbolAtPosition("/outside/src/foo.ts", "export const ".length); assert.ok(foo); @@ -2265,7 +2277,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `export const foo = 1;\nexport const bar = 2;\n`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const bar = await project.checker.getSymbolAtPosition("/src/foo.ts", "export const foo = 1;\nexport const ".length); assert.ok(bar); @@ -2285,7 +2297,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `const local = 1;\n`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/foo.ts", "const ".length); assert.ok(symbol); @@ -2300,7 +2312,7 @@ describe("LanguageService - imports", { concurrency }, () => { test("getImportAdderEdits rejects invalid actions", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/foo.ts", 13); assert.ok(symbol); @@ -2313,6 +2325,7 @@ describe("LanguageService - imports", { concurrency }, () => { () => project.languageService.getImportAdderEdits("/src/index.ts", [{ kind: "importSymbol", + // @ts-ignore -- Internal symbol identity is exercised by source tests. symbol: { ...symbol, reference: { ...symbol.reference, id: 999_999_999 } }, } as unknown as ImportAdderAction]), /symbol handle \d+ not found/, @@ -2328,7 +2341,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // Position right after "obj." — member completion trigger const pos = src.indexOf("obj.") + "obj.".length; @@ -2347,7 +2360,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("obj.") + "obj.".length; const completions = await project.languageService.getCompletionsAtPosition("/src/main.ts", pos, { triggerCharacter: "." }); @@ -2362,7 +2375,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": `export {};`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const completions = await project.languageService.getCompletionsAtPosition("/src/does-not-exist.ts", 0); assert.equal(completions, undefined, "Expected undefined for non-existent file"); @@ -2375,7 +2388,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("obj.") + "obj.".length; const completions = await project.languageService.getCompletionsAtPosition("/src/main.ts", pos, { triggerCharacter: ".", includeSymbol: true }); @@ -2395,7 +2408,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { }); const unprepared = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], userPreferences: { includeCompletionsForModuleExports: true } satisfies UserPreferences, }); const unpreparedProject = unprepared.getConfiguredProject("/tsconfig.json")!; @@ -2424,7 +2437,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { }); const snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], userPreferences: { includeCompletionsForModuleExports: false } satisfies UserPreferences, }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; @@ -2450,7 +2463,7 @@ describe("LanguageService - getReferencedSymbolsForNode", { concurrency }, () => "/src/index.ts": `function greet(name: string) { return name; }\ngreet("world");`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2472,7 +2485,7 @@ describe("LanguageService - getSignatureUsage", { concurrency }, () => { "/src/index.ts": `function greet(name: string) { return name; }\ngreet("world");`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2492,7 +2505,7 @@ describe("Checker - getApparentType", { concurrency }, () => { "/src/main.ts": `export const x = "hello" as const;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `export const x = "hello" as const;`.indexOf("x ="); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -2530,7 +2543,7 @@ class QuotaExceededError extends TaggedError("QuotaExceededError")<{ export type Result = RateLimitError | (RateLimitError & QuotaExceededError);`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -2552,7 +2565,7 @@ describe("Checker - getMemberInModuleExports", { concurrency }, () => { "/src/index.ts": `export const direct = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2573,7 +2586,7 @@ describe("SourceFile", { concurrency }, () => { "/outside/src/index.ts": "export const value = 1;", }); - const snapshot = await api.createSnapshot({ openProject: "/outside/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/outside/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/outside/tsconfig.json")!.program; const absolute = await program.getSourceFile("/outside/src/index.ts"); const relative = await program.getSourceFile("src/index.ts"); @@ -2585,7 +2598,7 @@ describe("SourceFile", { concurrency }, () => { test("getSourceFile rejects invalid document identifiers", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/tsconfig.json")!.program; const document = { fileName: "/src/index.ts" } as unknown as DocumentIdentifier; @@ -2612,7 +2625,7 @@ describe("SourceFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const bar: number;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const fileNames = await project.program.getSourceFileNames(); assert.deepEqual(fileNames, [ @@ -2634,7 +2647,7 @@ describe("SourceFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const bar: number;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const program = project.program; @@ -2671,7 +2684,7 @@ describe("SourceFile", { concurrency }, () => { "/esm/index.ts": `export const m = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/tsconfig.json")!.program; const mts = await program.getSourceFile("/src/esm.mts"); @@ -2697,7 +2710,7 @@ describe("SourceFile", { concurrency }, () => { test("file properties", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); @@ -2709,7 +2722,7 @@ describe("SourceFile", { concurrency }, () => { test("extended data", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); @@ -2743,7 +2756,7 @@ describe("SourceFile", { concurrency }, () => { "/input.ts": `let arrow = () => {}`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/input.ts"); @@ -2778,7 +2791,7 @@ describe("NodeArray", { concurrency }, () => { "/src/main.ts": `declare function foo(...args: any): void;\nfoo("a", "b",);\nfoo("a", "b");`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -2799,7 +2812,7 @@ describe("API objects", { concurrency }, () => { "/src/3.ts": `"\\ud800a\\udc00"`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const expectedTexts = new Map([ ["/src/1.ts", "😃"], @@ -2826,7 +2839,7 @@ describe("API objects", { concurrency }, () => { "/src/index.ts": "`\\ud800${0}\\udc00`", }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2851,7 +2864,7 @@ describe("API objects", { concurrency }, () => { test("Object equality", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // Same symbol returned from same snapshot's checker assert.strictEqual( @@ -2863,7 +2876,7 @@ describe("API objects", { concurrency }, () => { test("Snapshot dispose", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/index.ts", 9); assert.ok(symbol); @@ -2887,8 +2900,8 @@ describe("Multiple snapshots", { concurrency }, () => { test("two snapshots work independently", async () => { await using api = spawnAPI(); - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); - const snap2 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const snap2 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Both can fetch source files const sf1 = await snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); @@ -2911,7 +2924,7 @@ describe("Multiple snapshots", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); await using api = disposableAPI; - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Verify initial state const sf1 = await snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -2921,7 +2934,7 @@ describe("Multiple snapshots", { concurrency }, () => { // Mutate the file and create a new snapshot with the change fs.writeFile!(toRootedFilePath("/src/foo.ts", undefined), `export const foo = "changed";`); const snap2 = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); @@ -2942,7 +2955,7 @@ describe("Multiple snapshots", { concurrency }, () => { await snap2.dispose(); // Both are disposed, new snapshot works fine with latest content - const snap3 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap3 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf3 = await snap3.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); assert.ok(sf3); assert.equal(sf3.text, `export const foo = "changed";`); @@ -2952,12 +2965,12 @@ describe("Multiple snapshots", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); await using api = disposableAPI; - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Add a brand new file fs.writeFile!(toRootedFilePath("/src/bar.ts", undefined), `export const bar = true;`); const snap2 = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { created: ["/src/bar.ts"] }, }); @@ -2974,7 +2987,7 @@ describe("Multiple snapshots", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); await using api = disposableAPI; - await api.createSnapshot({ openProject: "/tsconfig.json" }); + await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const versions = [ `export const foo = 1;`, @@ -2985,7 +2998,7 @@ describe("Multiple snapshots", { concurrency }, () => { for (const version of versions) { fs.writeFile!(toRootedFilePath("/src/foo.ts", undefined), version); const snap = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); const sf = await snap.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -3093,7 +3106,7 @@ describe("Source file caching", { concurrency }, () => { test("same file from same snapshot returns cached object", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sf1 = await project.program.getSourceFile("/src/index.ts"); const sf2 = await project.program.getSourceFile("/src/index.ts"); @@ -3104,8 +3117,8 @@ describe("Source file caching", { concurrency }, () => { test("same file from two snapshots (same content) returns cached object", async () => { await using api = spawnAPI(); - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); - const snap2 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const snap2 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Fetch from snap1 first (populates cache), then snap2 (cache hit via hash) const sf1 = await snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); const sf2 = await snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); @@ -3119,7 +3132,7 @@ describe("Source file caching", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); await using api = disposableAPI; - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf1 = await snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); assert.ok(sf1); assert.equal(sf1.text, `export const foo = 42;`); @@ -3129,7 +3142,7 @@ describe("Source file caching", { concurrency }, () => { // Notify the server about the change const snap2 = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); const sf2 = await snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -3144,7 +3157,7 @@ describe("Source file caching", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); await using api = disposableAPI; - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf1 = await snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); assert.ok(sf1); @@ -3153,7 +3166,7 @@ describe("Source file caching", { concurrency }, () => { // Notify the server about the change to foo.ts only const snap2 = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); const sf2 = await snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); @@ -3166,12 +3179,12 @@ describe("Source file caching", { concurrency }, () => { test("disposing the source snapshot releases its cache entries", async () => { await using api = spawnAPI(); - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Fetch from snap1 to populate cache const sf1 = await snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); assert.ok(sf1); - const snap2 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap2 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); await snap1.dispose(); @@ -3184,7 +3197,7 @@ describe("Source file caching", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); await using api = disposableAPI; - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf1 = await snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); assert.ok(sf1); assert.equal(sf1.text, `export const foo = 42;`); @@ -3194,7 +3207,7 @@ describe("Source file caching", { concurrency }, () => { // Use invalidateAll to force re-fetch const snap2 = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { invalidateAll: true }, }); const sf2 = await snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -3212,7 +3225,7 @@ describe("Source file caching", { concurrency }, () => { await using api = disposableAPI; // Snapshot 1: get a node and verify getContextualType works - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const proj1 = snap1.getConfiguredProject("/tsconfig.json")!; const sf1 = await proj1.program.getSourceFile("/src/main.ts"); @@ -3232,7 +3245,7 @@ describe("Source file caching", { concurrency }, () => { // Snapshot 2: change a different file fs.writeFile!(toRootedFilePath("/src/other.ts", undefined), `export const x = 2;`); const snap2 = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/other.ts"] }, }); const proj2 = snap2.getConfiguredProject("/tsconfig.json")!; @@ -3261,7 +3274,7 @@ describe("Snapshot disposal", { concurrency }, () => { test("dispose is idempotent", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstDispose = snapshot.dispose(); const secondDispose = snapshot.dispose(); assert.strictEqual(firstDispose, secondDispose); @@ -3276,7 +3289,7 @@ describe("Snapshot disposal", { concurrency }, () => { const api = spawnAPI(); let snapshot: Snapshot; { - await using disposableSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + await using disposableSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); snapshot = disposableSnapshot; } assert.ok(snapshot.isDisposed()); @@ -3286,8 +3299,8 @@ describe("Snapshot disposal", { concurrency }, () => { test("api.close disposes all active snapshots", async () => { const api = spawnAPI(); - const snap1 = await api.createSnapshot({ openProject: "/tsconfig.json" }); - const snap2 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const snap2 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); assert.ok(!snap1.isDisposed()); assert.ok(!snap2.isDisposed()); await api.close(); @@ -3478,7 +3491,7 @@ export class MyClass { test("getTypeAtPosition", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const xPos = src.indexOf("x = 42"); @@ -3490,7 +3503,7 @@ export class MyClass { test("getTypeAtPosition batched", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const xPos = src.indexOf("x = 42"); @@ -3504,7 +3517,7 @@ export class MyClass { test("getTypeAtLocation", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -3531,7 +3544,7 @@ const c = obj.b.c; await using api = spawnAPI(files); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -3577,12 +3590,12 @@ export class Cache { await using api = spawnAPI(files); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); - let callNode: import("@typescript/typescript/unstable/ast").CallExpression | undefined; + let callNode: import("@typescript/typescript/ast").CallExpression | undefined; sourceFile.forEachChild(function visit(node) { if (isCallExpression(node)) { const text = sourceFile.text.slice(node.pos, node.end).trim(); @@ -3614,7 +3627,7 @@ export class Cache { test("getSignaturesOfType - call signatures", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const addPos = src.indexOf("add("); @@ -3639,7 +3652,7 @@ export class Cache { test("getApparentProperties includes CallableFunction members", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3658,7 +3671,7 @@ export class Cache { collectTiming: true, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3703,7 +3716,7 @@ export class Cache { test("getSignaturesOfType - construct signatures", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const classPos = src.indexOf("MyClass"); @@ -3720,7 +3733,7 @@ export class Cache { test("Signature declaration can be resolved", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const addPos = src.indexOf("add("); @@ -3771,7 +3784,7 @@ export class Cache { "/src/main.ts": mainFile, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const liftPos = mainFile.indexOf("lift"); const type = await project.checker.getTypeAtPosition("/src/main.ts", liftPos); @@ -3791,7 +3804,7 @@ export class Cache { test("Signature.getParameters() returns parameter symbols with correct names", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3811,7 +3824,7 @@ export class Cache { test("Signature.getThisParameter() returns undefined when no explicit this parameter", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3831,7 +3844,7 @@ export class Cache { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("foo(")); assert.ok(symbol); @@ -3848,7 +3861,7 @@ export class Cache { test("Signature.getTarget() returns undefined for a non-instantiated signature", async () => { await using api = spawnAPI(checkerFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3871,7 +3884,7 @@ export class Cache { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -3905,7 +3918,7 @@ export const value = 1; test("getMembers returns class members", async () => { await using api = spawnAPI(symbolFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = symbolFiles["/src/mod.ts"]; const animalPos = src.indexOf("Animal"); @@ -3921,7 +3934,7 @@ export const value = 1; test("getExports returns module exports via sourceFile symbol", async () => { await using api = spawnAPI(symbolFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/mod.ts"); assert.ok(sourceFile); @@ -3937,7 +3950,7 @@ export const value = 1; test("getParent returns containing symbol", async () => { await using api = spawnAPI(symbolFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = symbolFiles["/src/mod.ts"]; const namePos = src.indexOf("name:"); @@ -3952,7 +3965,7 @@ export const value = 1; test("checkFlags is typed as CheckFlags", async () => { await using api = spawnAPI(symbolFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/mod.ts", symbolFiles["/src/mod.ts"].indexOf("Animal")); assert.ok(symbol); @@ -3962,7 +3975,7 @@ export const value = 1; test("binder symbols are shared by file before the AST is fetched", async () => { await using api = spawnAPI(symbolFiles, { collectTiming: true }); - const firstSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; const secondSnapshot = await firstSnapshot.update({}); const secondProject = secondSnapshot.getConfiguredProject("/tsconfig.json")!; @@ -3984,7 +3997,7 @@ export const value = 1; test("file-owned symbol properties do not require a snapshot or project", async () => { await using api = spawnAPI(symbolFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/mod.ts"); assert.ok(sourceFile); @@ -4008,7 +4021,7 @@ export const value = 1; "/src/a.ts": `namespace Merged { export const a = 1; }`, "/src/b.ts": `namespace Merged { export const b = 1; }`, }); - const firstSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; const secondSnapshot = await firstSnapshot.update({}); const secondProject = secondSnapshot.getConfiguredProject("/tsconfig.json")!; @@ -4089,7 +4102,7 @@ export const value = 1; "/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true }, files: ["/src/box.ts"] }), "/src/box.ts": source, }, { collectTiming: true }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const box = await project.checker.getSymbolAtPosition("/src/box.ts", source.indexOf("Box")); assert.ok(box); @@ -4110,7 +4123,7 @@ export const value = 1; "/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true }, files: ["/src/box.ts"] }), "/src/box.ts": source, }); - const firstSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; // Create the second snapshot before the first symbol response populates // the client cache. This ensures its registry has no direct retain on @@ -4147,7 +4160,7 @@ export const value = 1; test("file-owned declarations resolve without the snapshot that observed them", async () => { await using api = spawnAPI(symbolFiles); - const firstSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; // Keeps the server AST alive after the observing snapshot is disposed. await using _secondSnapshot = await firstSnapshot.update({}); @@ -4163,12 +4176,12 @@ export const value = 1; test("file-owned symbols are accepted by later checkers while their file is unchanged", async () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...symbolFiles, "/src/other.ts": `export const other = 1;` }); await using api = disposableAPI; - const firstSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const animal = await firstSnapshot.getConfiguredProject("/tsconfig.json")!.checker.getSymbolAtPosition("/src/mod.ts", symbolFiles["/src/mod.ts"].indexOf("Animal")); assert.ok(animal); fs.writeFile!(toRootedFilePath("/src/other.ts", undefined), `export const other = 2;`); - const secondSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json", fileNotifications: { changed: ["/src/other.ts"] } }); + const secondSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/other.ts"] } }); const type = await secondSnapshot.getConfiguredProject("/tsconfig.json")!.checker.getTypeOfSymbol(animal); assert.ok(type); assert.strictEqual(await type.getSymbol(), animal); @@ -4177,12 +4190,12 @@ export const value = 1; test("file-owned symbols are rejected by checkers whose program has a different version of their file", async () => { const { api: disposableAPI, fs } = spawnAPIWithFS(symbolFiles); await using api = disposableAPI; - const firstSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const animal = await firstSnapshot.getConfiguredProject("/tsconfig.json")!.checker.getSymbolAtPosition("/src/mod.ts", symbolFiles["/src/mod.ts"].indexOf("Animal")); assert.ok(animal); fs.writeFile!(toRootedFilePath("/src/mod.ts", undefined), `${symbolFiles["/src/mod.ts"]}\nexport const added = 2;`); - const secondSnapshot = await api.createSnapshot({ openProject: "/tsconfig.json", fileNotifications: { changed: ["/src/mod.ts"] } }); + const secondSnapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/mod.ts"] } }); const secondProject = secondSnapshot.getConfiguredProject("/tsconfig.json")!; await assert.rejects(secondProject.checker.getTypeOfSymbol(animal), /source file is not part of the requested program/); // @sync: assert.throws(() => secondProject.checker.getTypeOfSymbol(animal), /source file is not part of the requested program/); }); @@ -4200,7 +4213,7 @@ export const instance: Foo = new Foo(); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Foo {\n x: number = 0;\n}\nexport const instance: Foo = new Foo();\n`; const instancePos = src.indexOf("instance"); @@ -4235,7 +4248,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; }; async function getTypeAtName(api: API, name: string) { - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = typeFiles["/src/types.ts"]; const pos = src.indexOf(name); @@ -4300,7 +4313,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // `string` is neither a union/intersection nor a template literal type, @@ -4323,7 +4336,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("IndexType.getTarget() returns the target type", async () => { await using api = spawnAPI(typeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.resolveName("KeyOf", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4339,7 +4352,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("IndexedAccessType.getObjectType() and getIndexType()", async () => { await using api = spawnAPI(typeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.resolveName("Lookup", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4357,7 +4370,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("ConditionalType.getCheckType() and getExtendsType()", async () => { await using api = spawnAPI(typeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.resolveName("Cond", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4375,7 +4388,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("ConditionalType.getTrueType() and getFalseType()", async () => { await using api = spawnAPI(typeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.resolveName("Cond", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4397,7 +4410,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("MappedType exposes its component types", async () => { await using api = spawnAPI(typeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.resolveName("Mapped", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4414,7 +4427,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("MappedType returned as a union constituent exposes its component types", async () => { await using api = spawnAPI(typeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.resolveName("MappedUnion", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4444,7 +4457,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("StringMappingType.getTarget() returns the mapped type", async () => { await using api = spawnAPI(typeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = typeFiles["/src/types.ts"]; const pos = src.indexOf("Upper"); @@ -4474,7 +4487,7 @@ array([]); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -4526,7 +4539,7 @@ export function gh1449(a: T): T { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -4564,7 +4577,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getAnyType returns a type with Any flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getAnyType(); assert.ok(type); @@ -4574,7 +4587,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getStringType returns a type with String flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getStringType(); assert.ok(type); @@ -4584,7 +4597,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNumberType returns a type with Number flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getNumberType(); assert.ok(type); @@ -4594,7 +4607,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getBooleanType returns a type with Boolean flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getBooleanType(); assert.ok(type); @@ -4604,7 +4617,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getVoidType returns a type with Void flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getVoidType(); assert.ok(type); @@ -4614,7 +4627,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getUndefinedType returns a type with Undefined flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getUndefinedType(); assert.ok(type); @@ -4624,7 +4637,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNullType returns a type with Null flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getNullType(); assert.ok(type); @@ -4634,7 +4647,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNeverType returns a type with Never flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getNeverType(); assert.ok(type); @@ -4644,7 +4657,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getUnknownType returns a type with Unknown flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getUnknownType(); assert.ok(type); @@ -4654,7 +4667,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getBigIntType returns a type with BigInt flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getBigIntType(); assert.ok(type); @@ -4664,7 +4677,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getESSymbolType returns a type with ESSymbol flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getESSymbolType(); assert.ok(type); @@ -4674,7 +4687,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNonPrimitiveType returns a type with NonPrimitive flag", async () => { await using api = spawnAPI(intrinsicFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = await project.checker.getNonPrimitiveType(); assert.ok(type); @@ -4795,7 +4808,7 @@ describe("Checker - getBaseTypeOfLiteralType", { concurrency }, () => { "/src/main.ts": `export const x = 42;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const x = 42;`; const pos = src.indexOf("x ="); @@ -4815,7 +4828,7 @@ describe("Checker - getBaseTypeOfLiteralType", { concurrency }, () => { "/src/main.ts": `export const s = "hello";`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const s = "hello";`; const pos = src.indexOf("s "); @@ -4840,7 +4853,7 @@ foo(42); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); @@ -4850,7 +4863,7 @@ foo(42); // statement[1] = foo(42); which is an ExpressionStatement -> CallExpression const callStmt = sourceFile.statements[1]; assert.ok(callStmt); - let numLiteral: import("@typescript/typescript/unstable/ast").Expression | undefined; + let numLiteral: import("@typescript/typescript/ast").Expression | undefined; callStmt.forEachChild(function visit(node) { if (isCallExpression(node)) { // First argument @@ -4879,7 +4892,7 @@ export function check(x: string | number) { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport function check(x: string | number) {\n if (typeof x === "string") {\n return x;\n }\n return x;\n}\n`; @@ -4902,7 +4915,7 @@ export function check(x: string | number) { const funcDecl = sourceFile.statements[0]; assert.ok(funcDecl); // Walk to find the first "return x" — inside the if, x should be narrowed to string - let firstReturnX: import("@typescript/typescript/unstable/ast").Node | undefined; + let firstReturnX: import("@typescript/typescript/ast").Node | undefined; funcDecl.forEachChild(function visit(node) { if (isReturnStatement(node) && !firstReturnX) { // The expression of the return statement is the identifier "x" @@ -4930,7 +4943,7 @@ export const obj = { name }; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); @@ -4938,7 +4951,7 @@ export const obj = { name }; // Find the shorthand property assignment { name } // statement[1] = export const obj = { name }; - let shorthandNode: import("@typescript/typescript/unstable/ast").Node | undefined; + let shorthandNode: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (isShorthandPropertyAssignment(node)) { shorthandNode = node; @@ -4994,7 +5007,7 @@ describe("readFile callback semantics", { concurrency }, () => { const callbacks: FileSystemCallbacks = { ...fs, realpath }; await using api = new API({ cwd: "/", fs: callbacks }); - await using snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + await using snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); assert.ok( (await snapshot.getConfiguredProject("/tsconfig.json")!.program.getSourceFileNames()) .includes(toRootedFilePath("/node_modules/pkg/index.d.ts", undefined)), @@ -5051,7 +5064,7 @@ describe("readFile callback semantics", { concurrency }, () => { fs, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // 1. String content: virtual file is found @@ -5084,7 +5097,7 @@ describe("readFile callback semantics", { concurrency }, () => { fs: createVirtualFileSystem(files), useCaseSensitiveFileNames: false, }); - const program = (await api.createSnapshot({ openProject: "/tsconfig.json" })).getConfiguredProject("/tsconfig.json")!.program; + const program = (await api.createSnapshot({ openProjects: ["/tsconfig.json"] })).getConfiguredProject("/tsconfig.json")!.program; assert.ok(await program.getSourceFile("/SRC/INDEX.TS")); } { @@ -5093,7 +5106,7 @@ describe("readFile callback semantics", { concurrency }, () => { fs: createVirtualFileSystem(files), useCaseSensitiveFileNames: true, }); - const program = (await api.createSnapshot({ openProject: "/tsconfig.json" })).getConfiguredProject("/tsconfig.json")!.program; + const program = (await api.createSnapshot({ openProjects: ["/tsconfig.json"] })).getConfiguredProject("/tsconfig.json")!.program; assert.equal(await program.getSourceFile("/SRC/INDEX.TS"), undefined); } }); @@ -5213,7 +5226,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5238,7 +5251,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystemWithLib(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true }, files: ["src/main.ts"] }), "/src/main.ts": `export const values: Array = [];`, @@ -5312,7 +5325,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: { kind: "layer", files: { @@ -5345,7 +5358,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystemLayer([ ["/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true }, include: ["src/**/*.ts"] })], ["/src/from-cache.ts", `export const cache = true;`], @@ -5378,7 +5391,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); await using snapshot = await api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5419,7 +5432,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); await using snapshot = await api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5445,7 +5458,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true }, @@ -5501,7 +5514,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); let snapshot: Snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem([ ["/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true }, files: ["pkg/index.ts"] })], ["/pkg/index.ts", ""], @@ -5539,7 +5552,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { await using snapshot = await api.createSnapshot(); await using replaced = await snapshot.update({ ensurePrograms: true, - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem([ ["/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true }, files: ["memory.ts", "host.ts"] })], ["/memory.ts", `export const source = "memory";`], @@ -5555,7 +5568,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem( Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true }, files: ["src/main.ts"] }), @@ -5607,7 +5620,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }, }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true, outDir: "/out", rootDir: "/src" }, files: ["src/main.ts"] }), "/src/main.ts": `export const value: number = 1;`, @@ -5637,7 +5650,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { fs: host, }); await using snapshot = await api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystemLayer(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true, outDir: "/out", rootDir: "/src" }, files: ["src/main.ts"] }), "/src/main.ts": `export const value: number = 1;`, @@ -5677,7 +5690,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); await using snapshot = await api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5712,7 +5725,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { fs: host, }); await using snapshot = await api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: createFileSystem([ ["/project/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true, moduleResolution: "node" }, files: ["index.ts"] })], ["/project/index.ts", `import { value } from "pkg"; export { value };`], @@ -5747,7 +5760,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const xs: number[] = [];`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const xs: number[] = [];`; const pos = src.indexOf("xs"); @@ -5765,7 +5778,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const xs: readonly number[] = [];`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const xs: readonly number[] = [];`; const pos = src.indexOf("xs"); @@ -5783,7 +5796,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const xs: Array = [];`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const xs: Array = [];`; const pos = src.indexOf("xs"); @@ -5801,7 +5814,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const tup: [number, string] = [1, "a"];`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const tup: [number, string] = [1, "a"];`; const pos = src.indexOf("tup"); @@ -5819,7 +5832,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const tup: readonly [number, string] = [1, "a"];`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const tup: readonly [number, string] = [1, "a"];`; const pos = src.indexOf("tup"); @@ -5837,7 +5850,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const str: string = "";`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const str: string = "";`; const pos = src.indexOf("str"); @@ -5864,7 +5877,7 @@ export type ReadonlyUser = Readonly; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -5890,7 +5903,7 @@ export type ReadonlyUser = Readonly; "/src/main.ts": `export const a = 1; export let b = 2;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const a = await checker.getSymbolAtPosition("/src/main.ts", "export const ".length); const b = await checker.getSymbolAtPosition("/src/main.ts", "export const a = 1; export let ".length); @@ -5924,7 +5937,7 @@ export type B = InstanceType; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -5948,7 +5961,7 @@ describe("Checker - getReturnTypeOfSignature", { concurrency }, () => { "/src/main.ts": `export function add(a: number, b: number): number { return a + b; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function add(a: number, b: number): number { return a + b; }`; const pos = src.indexOf("add("); @@ -5971,7 +5984,7 @@ describe("Checker - getRestTypeOfSignature", { concurrency }, () => { "/src/main.ts": `export function sum(...nums: number[]): number { return nums.reduce((a, b) => a + b, 0); }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function sum(...nums: number[]): number { return nums.reduce((a, b) => a + b, 0); }`; const pos = src.indexOf("sum("); @@ -5994,7 +6007,7 @@ describe("Checker - getTypePredicateOfSignature", { concurrency }, () => { "/src/main.ts": `export function isString(x: unknown): x is string { return typeof x === "string"; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function isString(x: unknown): x is string { return typeof x === "string"; }`; const pos = src.indexOf("isString("); @@ -6026,7 +6039,7 @@ export class Dog extends Animal { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Animal {\n isdog(): this is Dog { return this instanceof Dog; }\n}\nexport class Dog extends Animal {\n bark() {}\n}\n`; const pos = src.indexOf("isdog("); @@ -6047,7 +6060,7 @@ export class Dog extends Animal { "/src/main.ts": `export function assertIsString(x: unknown): asserts x is string { if (typeof x !== "string") throw new Error(); }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function assertIsString(x: unknown): asserts x is string { if (typeof x !== "string") throw new Error(); }`; const pos = src.indexOf("assertIsString("); @@ -6072,7 +6085,7 @@ export class Dog extends Animal { "/src/main.ts": `export function add(a: number, b: number): number { return a + b; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function add(a: number, b: number): number { return a + b; }`; const pos = src.indexOf("add("); @@ -6101,7 +6114,7 @@ export class Derived extends Base { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Base {\n x: number = 0;\n}\nexport class Derived extends Base {\n y: string = "";\n}\n`; const pos = src.indexOf("Derived"); @@ -6129,7 +6142,7 @@ export interface Dog extends Animal { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface Animal {\n name: string;\n}\nexport interface Dog extends Animal {\n bark(): void;\n}\n`; const pos = src.indexOf("Dog"); @@ -6155,7 +6168,7 @@ export type BoxOfString = Box; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6185,7 +6198,7 @@ export const n: number = 0; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Base {\n x: number = 0;\n}\nexport class Derived extends Base {\n y: string = "";\n}\nexport const n: number = 0;\n`; @@ -6218,7 +6231,7 @@ declare const bad: ThisTypeDoesNotExist; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\ndeclare const good: string;\ndeclare const bad: ThisTypeDoesNotExist;\n`; @@ -6248,7 +6261,7 @@ export type Alias = typeof value; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport const value = 1;\nexport type Alias = typeof value;\n`; @@ -6273,7 +6286,7 @@ notCallable(); "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6307,7 +6320,7 @@ export const value = 1; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6335,7 +6348,7 @@ export const obj: { a: number } = { a: 1 }; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport const obj: { a: number } = { a: 1 };\n`; const objSymbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("obj")); @@ -6368,7 +6381,7 @@ export { x as '${maliciousName}' }; "/src/main.ts": source, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const typesFile = await project.program.getSourceFile("/src/types.d.ts"); @@ -6442,7 +6455,7 @@ export const total = add(1, 2); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6504,7 +6517,7 @@ var measure = function (name) { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6539,7 +6552,7 @@ const cast = /** @type {number} */ (someValue); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6569,7 +6582,7 @@ export const answer = 42; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6597,7 +6610,7 @@ export const answer = 42; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6625,7 +6638,7 @@ const cast = /** @type {number} */ (someValue); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6651,7 +6664,7 @@ var measure = function (name) { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6687,7 +6700,7 @@ export function add(a: number, b: number): number { `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6719,7 +6732,7 @@ export declare const p: Person; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface Person {\n name: string;\n age: number;\n greet(): void;\n}\nexport declare const p: Person;\n`; const pos = src.indexOf("p: Person"); @@ -6748,7 +6761,7 @@ export declare const m: StringMap; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface StringMap {\n [key: string]: number;\n}\nexport declare const m: StringMap;\n`; const pos = src.indexOf("m: StringMap"); @@ -6777,7 +6790,7 @@ export declare const m: ReadonlyMap; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface ReadonlyMap {\n readonly [key: string]: number;\n}\nexport declare const m: ReadonlyMap;\n`; const pos = src.indexOf("m: ReadonlyMap"); @@ -6818,7 +6831,7 @@ export type Exported = number; test("exposes interface this types and checker operations", async () => { await using api = spawnAPI(files); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6861,7 +6874,7 @@ export type Exported = number; assert.notEqual(localSymbol.id, exportedSymbol.id); assert.strictEqual(await project.checker.getExportSymbolOfSymbol(localSymbol), exportedSymbol); - let call: import("@typescript/typescript/unstable/ast").CallExpression | undefined; + let call: import("@typescript/typescript/ast").CallExpression | undefined; sourceFile.forEachChild(function visit(node) { if (isCallExpression(node) && sourceFile.text.slice(node.expression.pos, node.expression.end).trim() === "consume") { call = node; @@ -6887,7 +6900,7 @@ describe("Checker - getConstraintOfTypeParameter", { concurrency }, () => { "/src/main.ts": `export function identity(x: T): T { return x; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function identity(x: T): T { return x; }`; const pos = src.indexOf("identity<"); @@ -6912,7 +6925,7 @@ describe("Checker - TypeParameter getters", { concurrency }, () => { "/src/main.ts": `export function f(x: T): T { return x; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function f(x: T): T { return x; }`; const pos = src.indexOf("f<"); @@ -6941,7 +6954,7 @@ describe("Checker - TypeParameter getters", { concurrency }, () => { "/src/main.ts": `export function f(x: T): T { return x; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function f(x: T): T { return x; }`; const pos = src.indexOf("f<"); @@ -6967,7 +6980,7 @@ describe("Checker - getTypeArguments", { concurrency }, () => { "/src/main.ts": `export const arr: Array = [1, 2, 3];`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const arr: Array = [1, 2, 3];`; const pos = src.indexOf("arr:"); @@ -6987,7 +7000,7 @@ describe("Checker - getTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // `string` is not a type reference. When getTypeArguments is reached @@ -7016,7 +7029,7 @@ describe("Checker - getBaseConstraintOfType", { concurrency }, () => { "/src/main.ts": `export function identity(x: T): T { return x; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function identity(x: T): T { return x; }`; const pos = src.indexOf("identity<"); @@ -7038,7 +7051,7 @@ describe("Checker - getBaseConstraintOfType", { concurrency }, () => { "/src/main.ts": `export const x: number = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `export const x: number = 1;`.indexOf("x:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7063,7 +7076,7 @@ export declare const p: Person; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface Person {\n name: string;\n age: number;\n}\nexport declare const p: Person;\n`; const pos = src.indexOf("p: Person"); @@ -7086,7 +7099,7 @@ describe("Checker - getConstantValue", { concurrency }, () => { "/src/main.ts": `export enum E { A = 1, B = 2 }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7117,7 +7130,7 @@ describe("Checker - getConstantValue", { concurrency }, () => { }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7143,7 +7156,7 @@ describe("Checker - getConstantValue", { concurrency }, () => { "/src/main.ts": `export enum Color { Red = "red" }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7165,7 +7178,7 @@ describe("Checker - getSignatureFromDeclaration", { concurrency }, () => { "/src/main.ts": `export function add(a: number, b: number): number { return a + b; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7194,7 +7207,7 @@ export { value as renamed }; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7218,7 +7231,7 @@ describe("Checker - getAliasedSymbol", { concurrency }, () => { "/src/main.ts": `import { foo } from "./foo";\nexport const usage = foo;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `import { foo } from "./foo";`.indexOf("foo }"); const aliasSymbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7243,7 +7256,7 @@ export class Standalone {} `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -7272,7 +7285,7 @@ export * from "./inner"; `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -7301,7 +7314,7 @@ function f() { test("returns symbols visible at a position", async () => { await using api = spawnAPI(scopeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = scopeFiles["/src/main.ts"].indexOf("return innerValue"); const symbols = await project.checker.getSymbolsInScope( @@ -7318,7 +7331,7 @@ function f() { test("returns type symbols when asked for type meaning at a node", async () => { await using api = spawnAPI(scopeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7333,7 +7346,7 @@ function f() { test("SymbolFlags.All includes both value and type meanings", async () => { await using api = spawnAPI(scopeFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = scopeFiles["/src/main.ts"].indexOf("return innerValue"); const symbols = await project.checker.getSymbolsInScope( @@ -7362,7 +7375,7 @@ export function add(a: number, b: number): number { return a + b; } test("getDocumentationComment returns the leading comment text", async () => { await using api = spawnAPI(docFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = docFiles["/src/main.ts"].indexOf("add(a"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7375,7 +7388,7 @@ export function add(a: number, b: number): number { return a + b; } test("getJsDocTags returns structured tag name/text pairs", async () => { await using api = spawnAPI(docFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = docFiles["/src/main.ts"].indexOf("add(a"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7398,7 +7411,7 @@ describe("TypeParameter - isThisType", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // ": this {" — offset 2 past ': ' lands on 't' in the return-type 'this' const pos = src.indexOf(": this {") + 2; @@ -7416,7 +7429,7 @@ describe("TypeParameter - isThisType", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // Point to 'T' in the type parameter declaration '' — getTypeAtPosition // on a type annotation reference doesn't resolve to TypeParameter, but @@ -7438,7 +7451,7 @@ describe("Type - getAliasTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("x:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7457,7 +7470,7 @@ describe("Type - getAliasTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("p:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7477,7 +7490,7 @@ describe("Type - getAliasTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("arr:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7498,7 +7511,7 @@ describe("Type - getAliasSymbol", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("p:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7517,7 +7530,7 @@ describe("Type - getAliasSymbol", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("c:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7536,7 +7549,7 @@ describe("Type - getAliasSymbol", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("str:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7556,7 +7569,7 @@ describe("IntrinsicType - intrinsicName", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const stringType = await project.checker.getStringType(); assert.equal((stringType as IntrinsicType).intrinsicName, "string"); @@ -7582,7 +7595,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("empty:")); assert.ok(symbol); @@ -7600,7 +7613,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("greeting:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7619,7 +7632,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const posSymbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("pos =")); @@ -7648,7 +7661,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const posSymbol = await project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("pos =")); @@ -7677,7 +7690,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("greeting:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7705,7 +7718,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("greeting:"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7732,7 +7745,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("Pending"); const symbol = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7764,12 +7777,12 @@ describe("Checker - isContextSensitive", { concurrency }, () => { "/src/main.ts": `export const fn = (x) => x;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); // Find the arrow function node - let arrowFn: import("@typescript/typescript/unstable/ast").Node | undefined; + let arrowFn: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (node.kind === SyntaxKind.ArrowFunction) { arrowFn = node; @@ -7789,7 +7802,7 @@ describe("Checker - isTypeAssignableTo", { concurrency }, () => { "/src/main.ts": `export {};`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const stringType = await project.checker.getStringType(); const anyType = await project.checker.getAnyType(); @@ -7805,7 +7818,7 @@ describe("Checker - isTypeAssignableTo", { concurrency }, () => { "/src/main.ts": `export {};`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const stringType = await project.checker.getStringType(); const numberType = await project.checker.getNumberType(); @@ -7820,7 +7833,7 @@ describe("Checker - isTypeAssignableTo", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("x:"); const sym = await project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7857,7 +7870,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printFile", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sourceFile = await snapshot.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/main.ts"); assert(sourceFile); const text = await api.printer.printFile(sourceFile); @@ -7883,7 +7896,7 @@ export const obj = { m: 1, s: "hi", b: true }; "/src/data.json": `{"x": 1}`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sourceFile = await snapshot.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/data.json"); assert(sourceFile); assert.strictEqual(await api.printer.printFile(sourceFile), `{ "x": 1 }\n`); @@ -7892,7 +7905,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created union type", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createUnionTypeNode([ createKeywordTypeNode(SyntaxKind.StringKeyword), @@ -7905,7 +7918,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created function type", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const param = createParameterDeclaration( undefined, @@ -7927,7 +7940,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created type reference", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createTypeReferenceNode(createIdentifier("Array"), [ createKeywordTypeNode(SyntaxKind.StringKeyword), @@ -7939,7 +7952,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created array type", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.NumberKeyword)); const text = await api.printer.printNode(node); @@ -7949,7 +7962,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("typeToTypeNode + printNode round-trip", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const src = emitterFiles["/src/main.ts"]; @@ -7968,7 +7981,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("visitEachChild on typeToTypeNode result with keyword types", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const src = emitterFiles["/src/main.ts"]; const objPos = src.indexOf("obj"); @@ -8016,7 +8029,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("typeToString", async () => { await using api = spawnAPI(emitterFiles); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const src = emitterFiles["/src/main.ts"]; @@ -8035,7 +8048,7 @@ export const obj = { m: 1, s: "hi", b: true }; "/src/main.ts": `export function greet(name: string): string[] { return [name]; }`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const greetPos = "export function greet".indexOf("greet"); const symbol = await checker.getSymbolAtPosition("/src/main.ts", greetPos); @@ -8052,13 +8065,13 @@ export const obj = { m: 1, s: "hi", b: true }; "/src/main.ts": `const foo = /asdfasf;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); // Find the regex literal node - let regexNode: import("@typescript/typescript/unstable/ast").Node | undefined; + let regexNode: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (node.kind === SyntaxKind.RegularExpressionLiteral) { regexNode = node; @@ -8097,7 +8110,7 @@ describe("Program - selected file emit", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...files }); await using api = disposableAPI; - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.getJavaScriptEmit(["/src/a.ts", "/src/b.ts"]); assert.equal(result.emitSkipped, false); @@ -8117,7 +8130,7 @@ describe("Program - selected file emit", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...files }); await using api = disposableAPI; - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.getDeclarationEmit(["/src/a.ts", "/src/b.ts"]); assert.equal(result.emitSkipped, false); @@ -8134,14 +8147,14 @@ describe("Program - selected file emit", { concurrency }, () => { test("selected file emit accepts empty arrays", async () => { await using api = spawnAPI({ ...files }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; assert.deepEqual((await project.program.getJavaScriptEmit([])).outputFiles, new Map()); assert.deepEqual((await project.program.getDeclarationEmit([])).outputFiles, new Map()); }); }); -describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => { +describe("LanguageService - formatNodeForInsertion", { concurrency }, () => { test("formats a synthesized statement with correct indentation for insertion inside a function body", async () => { const files = { "/tsconfig.json": "{}", @@ -8149,7 +8162,8 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => }; await using api = spawnAPI(files); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const languageService = snapshot.getConfiguredProject("/tsconfig.json")!.languageService; const node = createVariableStatement( undefined, @@ -8162,7 +8176,7 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => const sourceText = files["/src/index.ts"]; const insertionPos = sourceText.indexOf("\n console.log") + 1; - const formatted = await snapshot.internal.formatNodeForInsertion(node, "/src/index.ts", insertionPos); + const formatted = await languageService.formatNodeForInsertion(node, "/src/index.ts", insertionPos); assert.ok(formatted.includes("const x = 1;"), `Expected 'const x = 1;' in formatted output, got: ${JSON.stringify(formatted)}`); assert.ok(formatted.startsWith(" "), `Expected 4 spaces of indentation, got: ${JSON.stringify(formatted)}`); }); @@ -8174,7 +8188,8 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => }; await using api = spawnAPI(files); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const languageService = snapshot.getConfiguredProject("/tsconfig.json")!.languageService; const node = createVariableStatement( undefined, @@ -8184,7 +8199,7 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => ), ); - const formatted = await snapshot.internal.formatNodeForInsertion(node, "/src/index.ts", 0); + const formatted = await languageService.formatNodeForInsertion(node, "/src/index.ts", 0); assert.ok(formatted.includes("const y = 42;"), `Expected 'const y = 42;' in formatted output, got: ${JSON.stringify(formatted)}`); assert.ok(!formatted.startsWith(" "), `Expected no leading spaces at top level, got: ${JSON.stringify(formatted)}`); }); @@ -8198,7 +8213,8 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => }; await using api = spawnAPI(files); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const languageService = snapshot.getConfiguredProject("/tsconfig.json")!.languageService; const node = createVariableStatement( undefined, @@ -8212,7 +8228,7 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => const sourceText = files["/src/index.ts"]; const insertionPos = sourceText.indexOf("\n console.log") + 1; - const formatted = await snapshot.internal.formatNodeForInsertion(node, "/src/index.ts", insertionPos); + const formatted = await languageService.formatNodeForInsertion(node, "/src/index.ts", insertionPos); // The node should be indented to match the function body (4 spaces) assert.ok(formatted.includes("const x = 1;"), `Expected 'const x = 1;' in formatted output, got: ${JSON.stringify(formatted)}`); assert.ok(formatted.startsWith(" "), `Expected 4 spaces of indentation (UTF-16 offset correctly converted), got: ${JSON.stringify(formatted)}`); @@ -8226,12 +8242,12 @@ describe("modifierFlags", { concurrency }, () => { "/src/index.ts": `export async function foo() {}`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let fnNode: import("@typescript/typescript/unstable/ast").FunctionDeclaration | undefined; + let fnNode: import("@typescript/typescript/ast").FunctionDeclaration | undefined; sourceFile.forEachChild(function visit(node) { if (isFunctionDeclaration(node)) { fnNode = node; @@ -8250,12 +8266,12 @@ describe("modifierFlags", { concurrency }, () => { "/src/index.ts": `function bar() {}`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let fnNode: import("@typescript/typescript/unstable/ast").FunctionDeclaration | undefined; + let fnNode: import("@typescript/typescript/ast").FunctionDeclaration | undefined; sourceFile.forEachChild(function visit(node) { if (isFunctionDeclaration(node)) { fnNode = node; @@ -8274,13 +8290,13 @@ describe("Checker - getResolvedSymbol", { concurrency }, () => { "/src/index.ts": `const x = 1;\nconst y = x;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); // Find the 'x' identifier in `const y = x` - let refNode: import("@typescript/typescript/unstable/ast").Identifier | undefined; + let refNode: import("@typescript/typescript/ast").Identifier | undefined; sourceFile.forEachChild(function visit(node) { if (isIdentifier(node) && node.text === "x") { // We want the reference, not the declaration - take the last one @@ -8303,12 +8319,12 @@ describe("VariableDeclarationList - BlockScoped flags", { concurrency }, () => { "/src/index.ts": `let x = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let declList: import("@typescript/typescript/unstable/ast").Node | undefined; + let declList: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (isVariableDeclarationList(node)) { declList = node; @@ -8325,12 +8341,12 @@ describe("VariableDeclarationList - BlockScoped flags", { concurrency }, () => { "/src/index.ts": `const x = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let declList: import("@typescript/typescript/unstable/ast").Node | undefined; + let declList: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (isVariableDeclarationList(node)) { declList = node; @@ -8349,13 +8365,13 @@ describe("AST roundtrips", { concurrency }, () => { "/src/index.ts": `function test(arg: readonly number[]) { }\n`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert(sourceFile); - const param = (sourceFile.statements[0] as import("@typescript/typescript/unstable/ast").FunctionDeclaration).parameters[0]; + const param = (sourceFile.statements[0] as import("@typescript/typescript/ast").FunctionDeclaration).parameters[0]; assert(param); - const type = param.type as import("@typescript/typescript/unstable/ast").TypeOperatorNode; + const type = param.type as import("@typescript/typescript/ast").TypeOperatorNode; assert(type); assert.equal(type.kind, SyntaxKind.TypeOperator); assert.equal(type.operator, SyntaxKind.ReadonlyKeyword); @@ -8369,13 +8385,13 @@ describe("AST roundtrips", { concurrency }, () => { "/src/index.ts": `var thing = { ...other };\n`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert(sourceFile); - const stmt = sourceFile.statements[0] as import("@typescript/typescript/unstable/ast").VariableStatement; - const object = stmt.declarationList.declarations[0].initializer as import("@typescript/typescript/unstable/ast").ObjectLiteralExpression; - const assignment = object.properties[0] as import("@typescript/typescript/unstable/ast").SpreadAssignment; + const stmt = sourceFile.statements[0] as import("@typescript/typescript/ast").VariableStatement; + const object = stmt.declarationList.declarations[0].initializer as import("@typescript/typescript/ast").ObjectLiteralExpression; + const assignment = object.properties[0] as import("@typescript/typescript/ast").SpreadAssignment; assert(assignment); assert.equal(assignment.kind, SyntaxKind.SpreadAssignment); const expr = assignment.expression; @@ -8391,18 +8407,18 @@ describe("AST roundtrips", { concurrency }, () => { "/src/index.ts": `const thing = 123;\n`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert(sourceFile); { - const stmt = sourceFile.statements[0] as import("@typescript/typescript/unstable/ast").VariableStatement; + const stmt = sourceFile.statements[0] as import("@typescript/typescript/ast").VariableStatement; const list = stmt.declarationList; assert(list.flags & NodeFlags.Const); } const cloned = getSynthesizedDeepClone(sourceFile); { - const stmt = cloned.statements[0] as import("@typescript/typescript/unstable/ast").VariableStatement; + const stmt = cloned.statements[0] as import("@typescript/typescript/ast").VariableStatement; const list = stmt.declarationList; assert(list.flags & NodeFlags.Const); } @@ -8421,7 +8437,7 @@ doThing(); `, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert(sourceFile); @@ -8432,7 +8448,7 @@ doThing(); test("Factory ModifierList auto-conversion", async () => { await using api = spawnAPI(); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createTypeAliasDeclaration( [createToken(SyntaxKind.ExportKeyword)], @@ -8460,10 +8476,10 @@ doThing(); const errors = { ...target }; for (const tsconfig of globSync("**/tsconfig.json", { cwd: tsSource })) { - const snapshot = await api.createSnapshot({ openProject: resolve(tsSource, tsconfig) }); + const snapshot = await api.createSnapshot({ openProjects: [resolve(tsSource, tsconfig)] }); const project = snapshot.getConfiguredProject(tsconfig); assert(project); - for (const file of project.rootFiles) { + for (const file of project.parsedCommandLine.fileNames) { const source = await project.program.getSourceFile(file); assert(source); let clone: typeof source; @@ -8506,7 +8522,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getSyntacticDiagnostics("/src/index.ts"); assert.deepEqual(diags[0].startPosition, { line: 0, character: 9 }); @@ -8528,7 +8544,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getSemanticDiagnostics("/src/index.ts"); const declRange = rangeOf(source, "callback", 0); @@ -8570,7 +8586,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getSuggestionDiagnostics("/src/index.ts"); assert.deepEqual(withoutFormattingContext(diags), [{ @@ -8590,7 +8606,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getConfigFileParsingDiagnostics(); assert.deepEqual(withoutFormattingContext(diags), [{ @@ -8611,7 +8627,7 @@ describe("Program - diagnostics", { concurrency }, () => { }); await using api = disposableAPI; - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const names = await project.program.getConfigFileNames(); assert.deepEqual(names, ["/tsconfig.json", "/tsconfig.base.json"]); @@ -8641,7 +8657,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x: number = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getDeclarationDiagnostics("/src/index.ts"); assert.deepEqual(diags, []); @@ -8654,7 +8670,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getBindDiagnostics("/src/index.ts"); assert.deepEqual(withoutFormattingContext(diags), [ @@ -8682,7 +8698,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getProgramDiagnostics(); assert.deepEqual(withoutFormattingContext(diags), [ @@ -8709,7 +8725,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getGlobalDiagnostics(); assert.deepEqual(diags, []); @@ -8721,7 +8737,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = [1, 2, 3];`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getGlobalDiagnostics(); // With noLib, the checker reports "Cannot find global type" diagnostics that @@ -8748,7 +8764,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/clean.ts": `const c = 3;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getSyntacticDiagnostics(["/src/a.ts", "/src/b.ts"]); assert.deepEqual(withoutFormattingContext(diags), [ @@ -8778,7 +8794,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": sourceB, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getSemanticDiagnostics(["/src/a.ts", "/src/b.ts"]); assert.equal(diags.length, 2); @@ -8797,7 +8813,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": sourceB, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getBindDiagnostics(["/src/a.ts", "/src/b.ts"]); assert.equal(diags.length, 4); @@ -8812,7 +8828,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": `const b: = 2;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getSyntacticDiagnostics(); assert.equal(diags.length, 2); @@ -8825,7 +8841,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": `const b: = 2;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = await project.program.getSyntacticDiagnostics([]); assert.deepEqual(diags, []); @@ -8882,7 +8898,7 @@ describe("getDefaultProjectForFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const foo: string;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // The d.ts is not imported, so it is not in the project's program @@ -8998,7 +9014,7 @@ describe("getDefaultProjectForFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const foo: string;`, }); - await api.createSnapshot({ openProject: "/tsconfig.json" }); + await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const opened = await api.createSnapshot({ openFiles: ["/node_modules/my-lib/index.d.ts"] }); assert.ok( await opened.getDefaultProjectForFile("/node_modules/my-lib/index.d.ts"), @@ -9034,7 +9050,7 @@ describe("Program - emit", { concurrency }, () => { fs: fs, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.emit(); assert.deepEqual(result, { @@ -9067,7 +9083,7 @@ describe("Program - emit", { concurrency }, () => { fs: fs, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.emit(EmitOnly.OnlyDts); assert.deepEqual(result, { @@ -9098,7 +9114,7 @@ describe("Program - emit", { concurrency }, () => { fs: fs, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.emit(EmitOnly.OnlyJs); assert.deepEqual(result, { @@ -9125,7 +9141,7 @@ describe("Program - emit", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...files }); await using api = disposableAPI; - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.emitToString(EmitOnly.OnlyDts); assert.deepEqual([...result.outputFiles.keys()], [ @@ -9149,7 +9165,7 @@ describe("Program - emit", { concurrency }, () => { }); await using api = disposableAPI; - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.emit(); @@ -9191,7 +9207,7 @@ describe("Program - emit", { concurrency }, () => { }); await using api = disposableAPI; - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.emit(); assert.equal(result.emitSkipped, true); @@ -9213,7 +9229,7 @@ describe("Program - emit", { concurrency }, () => { }); await using api = disposableAPI; - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; assert.deepEqual(await project.program.emit(), { diagnostics: [], @@ -9232,7 +9248,7 @@ describe("Program - emit", { concurrency }, () => { test("emit rejects unknown files and invalid emitOnly values", async () => { await using api = spawnAPI({ ...files }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; let error: unknown; @@ -9265,7 +9281,7 @@ describe("Program - emit", { concurrency }, () => { fs, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = await project.program.emit(); assert.deepEqual(result.emittedFiles, []); @@ -9289,7 +9305,7 @@ describe("Timing", { concurrency }, () => { assert.equal(info.recentRequests.length, 0); // Exercise a JSON request and a binary source-file request. - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -9348,7 +9364,7 @@ describe("Timing", { concurrency }, () => { collectTiming: true, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = await project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -9417,7 +9433,7 @@ describe("runWithTemporaryFileUpdate", { concurrency }, () => { "/src/index.ts": `export const x: number = 1;`, }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // The original content type-checks cleanly. @@ -9442,7 +9458,7 @@ describe("runWithTemporaryFileUpdate", { concurrency }, () => { assert.equal(afterDiags.length, 0); // A subsequent independent snapshot can request the project again. - const snapshot2 = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot2 = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project2 = snapshot2.getConfiguredProject("/tsconfig.json")!; const diags2 = await project2.program.getSemanticDiagnostics("/src/index.ts"); assert.equal(diags2.length, 0); diff --git a/packages/typescript/test/async/api.testUtils.ts b/packages/typescript/test/async/api.testUtils.ts index d141caa90c80e..04e45ff6489e8 100644 --- a/packages/typescript/test/async/api.testUtils.ts +++ b/packages/typescript/test/async/api.testUtils.ts @@ -1,7 +1,7 @@ import { API, type APIOptions, -} from "@typescript/typescript/unstable/async"; +} from "@typescript/typescript/async"; import { fileURLToPath } from "node:url"; import { createVirtualFileSystem } from "../testUtils.ts"; diff --git a/packages/typescript/test/async/astnav.test.ts b/packages/typescript/test/async/astnav.test.ts index 38595fb6d6afa..5bdd4c0655089 100644 --- a/packages/typescript/test/async/astnav.test.ts +++ b/packages/typescript/test/async/astnav.test.ts @@ -1,6 +1,6 @@ -import { API } from "@typescript/typescript/unstable/async"; // @sync-skip +import { API } from "@typescript/typescript/async"; // @sync-skip // @sync-only-start -// import { API } from "@typescript/typescript/unstable/sync"; +// import { API } from "@typescript/typescript/sync"; // @sync-only-end import { findNextToken, @@ -8,11 +8,11 @@ import { formatSyntaxKind, getTokenAtPosition, getTouchingPropertyName, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import type { Node, SourceFile, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import assert from "node:assert"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; @@ -106,7 +106,7 @@ describe("astnav", { concurrency: areTestsFiltered() }, () => { }), }); - const snapshot = await api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sf = await project.program.getSourceFile("/src/testFile.ts"); assert.ok(sf, "Failed to get source file from API"); diff --git a/packages/typescript/test/diagnosticFormatter.test.ts b/packages/typescript/test/diagnosticFormatter.test.ts index acb4091b66105..67429bc24676f 100644 --- a/packages/typescript/test/diagnosticFormatter.test.ts +++ b/packages/typescript/test/diagnosticFormatter.test.ts @@ -3,7 +3,7 @@ import { formatDiagnostics, type FormatDiagnosticsHost, formatDiagnosticsWithColorAndContext, -} from "@typescript/typescript/unstable/async"; +} from "@typescript/typescript/async"; import assert from "node:assert"; import { describe, @@ -22,7 +22,7 @@ describe("diagnosticFormatter", { concurrency: areTestsFiltered() }, () => { "/project/index.ts": source, }); try { - const snapshot = await api.createSnapshot({ openProject: "/project/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/project/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/project/tsconfig.json")!.program; const diagnostics = await program.getSemanticDiagnostics("/project/index.ts"); assert.equal(diagnostics.length, 1); @@ -100,7 +100,7 @@ describe("diagnosticFormatter", { concurrency: areTestsFiltered() }, () => { "/workspace/index.ts": `const x: number = "oops";`, }); try { - const snapshot = await api.createSnapshot({ openProject: "/workspace/tsconfig.json" }); + const snapshot = await api.createSnapshot({ openProjects: ["/workspace/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/workspace/tsconfig.json")!.program; const diagnostics = await program.getSemanticDiagnostics("/workspace/index.ts"); const configDiagnostics = (await api.parseConfigFile("/workspace/tsconfig.json")).errors; diff --git a/packages/typescript/test/encoder.test.ts b/packages/typescript/test/encoder.test.ts index 8b48997dd9eaa..a3d09ad64ea22 100644 --- a/packages/typescript/test/encoder.test.ts +++ b/packages/typescript/test/encoder.test.ts @@ -1,11 +1,11 @@ import type { SourceFile, Statement, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { SyntaxKind, TokenFlags, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { createArrayLiteralExpression, createBlock, @@ -25,12 +25,12 @@ import { createVariableDeclaration, createVariableDeclarationList, createVariableStatement, -} from "@typescript/typescript/unstable/ast/factory"; +} from "@typescript/typescript/ast/factory"; import { CaseSensitivity, pathKey, toRootedFilePath, -} from "@typescript/typescript/unstable/path"; +} from "@typescript/typescript/path"; import assert from "node:assert"; import { describe, diff --git a/packages/typescript/test/generators/api.bench.ts b/packages/typescript/test/generators/api.bench.ts index ddc3328e827b0..62530af1f2be2 100644 --- a/packages/typescript/test/generators/api.bench.ts +++ b/packages/typescript/test/generators/api.bench.ts @@ -10,12 +10,12 @@ import { type Node, type SourceFile, SyntaxKind, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { API, type Project, type Snapshot, -} from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/sync"; import { writeFileSync } from "node:fs"; import inspector from "node:inspector"; import path from "node:path"; @@ -200,7 +200,7 @@ export function runBenchmarks(options?: { filter?: string; singleIteration?: boo } function loadSnapshot() { - [snapshot] = api.batch(api.createSnapshot.gen({ openProject: "tsc/testdata/fixtures/compiler/tsconfig.json" })); + [snapshot] = api.batch(api.createSnapshot.gen({ openProjects: ["tsc/testdata/fixtures/compiler/tsconfig.json"] })); project = snapshot.getProjects()[0]; } diff --git a/packages/typescript/test/nodelist.bench.ts b/packages/typescript/test/nodelist.bench.ts index 42deb22bf23fc..45653c73686c7 100644 --- a/packages/typescript/test/nodelist.bench.ts +++ b/packages/typescript/test/nodelist.bench.ts @@ -14,19 +14,19 @@ import { type Statement, SyntaxKind, TokenFlags, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { createArrayLiteralExpression, createExpressionStatement, createNumericLiteral, createSourceFile, createToken, -} from "@typescript/typescript/unstable/ast/factory"; +} from "@typescript/typescript/ast/factory"; import { CaseSensitivity, pathKey, toRootedFilePath, -} from "@typescript/typescript/unstable/path"; +} from "@typescript/typescript/path"; import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; import { Bench } from "tinybench"; diff --git a/packages/typescript/test/path.test.ts b/packages/typescript/test/path.test.ts index 33f095077419c..ebcada46ece30 100644 --- a/packages/typescript/test/path.test.ts +++ b/packages/typescript/test/path.test.ts @@ -15,13 +15,14 @@ import { toRootedPath, tryPathKeyFromCanonical, tryRootedPathFromNormalized, -} from "@typescript/typescript/unstable/path"; +} from "@typescript/typescript/path"; import assert from "node:assert"; import { test } from "node:test"; import { parseNodeHandleFromCompiler } from "../src/api/node/node.ts"; import { documentURIToFileName, fileNameToDocumentURI, + // @ts-ignore -- Internal path helper is exercised by source tests. getRootLength, } from "../src/api/path.ts"; import { createVirtualFileSystem } from "./testUtils.ts"; diff --git a/packages/typescript/test/scanner.test.ts b/packages/typescript/test/scanner.test.ts index 0f52a34040628..fa4cc7d8f9e40 100644 --- a/packages/typescript/test/scanner.test.ts +++ b/packages/typescript/test/scanner.test.ts @@ -1,7 +1,7 @@ import { createScanner, SyntaxKind, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import assert from "node:assert"; import { test } from "node:test"; diff --git a/packages/typescript/test/spanMap.test.ts b/packages/typescript/test/spanMap.test.ts index 29e80e7a87bd6..0adc88654ae62 100644 --- a/packages/typescript/test/spanMap.test.ts +++ b/packages/typescript/test/spanMap.test.ts @@ -3,7 +3,7 @@ import { SpanMapFeature, SpanMapFidelity, SpanMapKind, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import assert from "node:assert"; import { describe, diff --git a/packages/typescript/test/sync/api-generators.test.ts b/packages/typescript/test/sync/api-generators.test.ts index 4a167fee90eb6..dbe13a87c3593 100644 --- a/packages/typescript/test/sync/api-generators.test.ts +++ b/packages/typescript/test/sync/api-generators.test.ts @@ -20,13 +20,13 @@ import { type Node, type SourceFile, SyntaxKind, -} from "@typescript/typescript/unstable/ast"; -import { cloneNode } from "@typescript/typescript/unstable/ast/factory"; -import { toRootedFilePath } from "@typescript/typescript/unstable/path"; +} from "@typescript/typescript/ast"; +import { cloneNode } from "@typescript/typescript/ast/factory"; +import { toRootedFilePath } from "@typescript/typescript/path"; import type { APIRequest, APIResponse, -} from "@typescript/typescript/unstable/proto"; +} from "@typescript/typescript/proto"; import { all, type AllAPIRequestGenerator, @@ -62,7 +62,7 @@ import { type TypePredicate, type TypeReference, type UnionOrIntersectionType, -} from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/sync"; import assert from "node:assert"; import { describe, @@ -157,9 +157,9 @@ const exercisedMethods = new Set(); const publicGeneratorExemptions = new Map([ ["API.fromLSPConnection", "requires an existing LSP API session"], ["API.getCurrentLanguageServerSnapshot", "requires an existing LSP API session"], - ["InternalAPI.startCPUProfile", "writes a CPU profile and changes process-global profiling state"], - ["InternalAPI.stopCPUProfile", "requires a matching active CPU profile"], - ["InternalAPI.saveHeapProfile", "writes a potentially large heap profile to disk"], + ["DebugHandlers.startCPUProfile", "writes a CPU profile and changes process-global profiling state"], + ["DebugHandlers.stopCPUProfile", "requires a matching active CPU profile"], + ["DebugHandlers.saveHeapProfile", "writes a potentially large heap profile to disk"], ]); const privateGeneratorGetters = new Set([ "API.ensureInitialized", @@ -342,7 +342,7 @@ function assertProjectsEquivalent(actual: Project, expected: Project, message?: assert.equal(actual.id, expected.id, message); assert.equal(actual.configFileName, expected.configFileName, message); assert.equal(actual.dirty, expected.dirty, message); - assert.deepEqual(actual.rootFiles, expected.rootFiles, message); + assert.deepEqual(actual.parsedCommandLine.fileNames, expected.parsedCommandLine.fileNames, message); } function assertOptionalProjectsEquivalent(actual: Project | undefined, expected: Project | undefined, message?: string): void { @@ -416,6 +416,7 @@ function observeRequestBatches( requestBatches: string[][], context: TestContext, ): void { + // @ts-ignore -- Internal client transport is exercised by source tests. const client = api["client"]; const batchRequests = client.batchRequests.bind(client); context.mock.method(client, "batchRequests", (requests: readonly APIRequest[]) => { @@ -1363,7 +1364,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => test("yields source file metadata requests on cache misses", () => { const api = spawnAPI(); try { - using snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + using snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/tsconfig.json")!.program; const sourceFile = program.getSourceFile("/src/index.ts")!; const state = program.getSourceFileMetadataByPath.gen(sourceFile.path).next(); @@ -1379,7 +1380,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => test("uses generators attached to sync API methods", () => { const api = spawnAPI(); try { - using snapshot = api.batch(api.createSnapshot.gen({ openProject: "/tsconfig.json" }))[0]; + using snapshot = api.batch(api.createSnapshot.gen({ openProjects: ["/tsconfig.json"] }))[0]; const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -1431,7 +1432,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => test("keeps every publicly reachable generator-backed method in sync", () => { const api = spawnAPI(parityFiles); try { - using snapshot = api.batch(api.createSnapshot.gen({ openProject: "/tsconfig.json" }))[0]; + using snapshot = api.batch(api.createSnapshot.gen({ openProjects: ["/tsconfig.json"] }))[0]; const project = snapshot.getConfiguredProject("/tsconfig.json")!; const { checker, languageService, program } = project; const { printer } = api; @@ -1559,7 +1560,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => timingGeneratorAPI.close(); timingSyncAPI.close(); - assert.ok(project.getImportAdderEdits("/src/index.ts", [{ kind: "importSymbol", symbol: unimportedSymbol }]).length > 0); + assert.ok(project.languageService.getImportAdderEdits("/src/index.ts", [{ kind: "importSymbol", symbol: unimportedSymbol }]).length > 0); assert.ok(program.getSyntacticDiagnostics("/src/syntax.ts").length > 0); assert.ok(program.getBindDiagnostics("/src/bind.ts").length > 0); assert.ok(program.getSuggestionDiagnostics("/src/suggestions.ts").length > 0); @@ -1594,8 +1595,9 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => parityCase("API", "transpileModuleFromFile", api.transpileModuleFromFile, assertDeepEquivalent, "/src/index.ts"), parityCase("API", "transpileDeclaration", api.transpileDeclaration, assertDeepEquivalent, "export function declared(value: string): number { return value.length; }"), parityCase("API", "transpileDeclarationFromFile", api.transpileDeclarationFromFile, assertDeepEquivalent, "/src/index.ts"), - parityCase("API", "createSnapshot", api.createSnapshot as GeneratorMethod<[params: { openProject: string; }], Snapshot>, assertSnapshotsEquivalent, { openProject: "/tsconfig.json" }), + parityCase("API", "createSnapshot", api.createSnapshot as GeneratorMethod<[params: { openProjects: string[]; }], Snapshot>, assertSnapshotsEquivalent, { openProjects: ["/tsconfig.json"] }), parityCase("API", "createProgram", api.createProgram, assertProgramsEquivalent, ["/src/index.ts"], { noLib: true }), + // @ts-ignore -- Internal API exercised by source tests. parityCase("API", "createBuildOrchestrator", api.createBuildOrchestrator, assertBuildOrchestratorsEquivalent, ["/tsconfig.json"], { cwd: "/" }), parityCase("API", "runWithTemporaryFileUpdate", api.runWithTemporaryFileUpdate, assertDeepEquivalent, snapshot, "/src/index.ts", parityFiles["/src/index.ts"].replace("123", '"fixed"'), (temporarySnapshot: Snapshot) => { temporaryProjects.push(temporarySnapshot.getProjects()[0].configFileName!); @@ -1604,14 +1606,12 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => parityCase("ModuleResolver", "resolveModuleName", moduleResolver.resolveModuleName, assertDeepEquivalent, "models", "/src"), parityCase("Snapshot", "update", snapshot.update, assertSnapshotsEquivalent, {}), - parityCase("Project", "getImportAdderEdits", project.getImportAdderEdits, assertDeepEquivalent, "/src/index.ts", [{ kind: "importSymbol", symbol: unimportedSymbol }]), - parityCase("Project", "getImportEditsForSymbols", project.getImportEditsForSymbols, assertDeepEquivalent, "/src/index.ts", [unimportedSymbol]), - parityCase("LanguageService", "getImportAdderEdits", languageService.getImportAdderEdits, assertDeepEquivalent, "/src/index.ts", [{ kind: "importSymbol", symbol: unimportedSymbol }]), parityCase("LanguageService", "getImportEditsForSymbols", languageService.getImportEditsForSymbols, assertDeepEquivalent, "/src/index.ts", [unimportedSymbol], { isValidTypeOnlyUseSite: true }), parityCase("LanguageService", "getReferencedSymbolsForNode", languageService.getReferencedSymbolsForNode, assertDeepEquivalent, combineDeclaration.name!, combineDeclaration.name!.end), parityCase("LanguageService", "getSignatureUsage", languageService.getSignatureUsage, assertDeepEquivalent, combineDeclaration), parityCase("LanguageService", "getCompletionsAtPosition", languageService.getCompletionsAtPosition, assertDeepEquivalent, "/src/index.ts", completionPosition, { includeSymbol: true }), + parityCase("LanguageService", "formatNodeForInsertion", languageService.formatNodeForInsertion, assertDeepEquivalent, combineDeclaration, "/src/index.ts", combineDeclaration.pos), parityCase("Program", "getSourceFile", program.getSourceFile, assertOptionalSourceFilesEquivalent, "/src/index.ts"), parityCase("Program", "getModeForUsageLocation", program.getModeForUsageLocation, assertDeepEquivalent, "/src/index.ts", importSpecifier), @@ -1660,9 +1660,6 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => parityCase("Checker", "getTypeOfSymbol", checker.getTypeOfSymbol, assertTypeArraysEquivalent, [derivedClassSymbol, combineSymbol]), parityCase("Checker", "getDeclaredTypeOfSymbol", checker.getDeclaredTypeOfSymbol, assertTypesEquivalent, interfaceSymbol), parityCase("Checker", "getReferencesToSymbolInFile", checker.getReferencesToSymbolInFile, assertNodeHandleArraysEquivalent, "/src/index.ts", derivedSymbol), - parityCase("Checker", "getReferencedSymbolsForNode", checker.getReferencedSymbolsForNode, assertDeepEquivalent, combineDeclaration.name!, combineDeclaration.name!.end), - parityCase("Checker", "getSignatureUsage", checker.getSignatureUsage, assertDeepEquivalent, combineDeclaration), - parityCase("Checker", "getCompletionsAtPosition", checker.getCompletionsAtPosition, assertDeepEquivalent, "/src/index.ts", completionPosition, { includeSymbol: true }), parityCase("Checker", "getTypeAtLocation", selectGeneratorMethod<[node: Node], Type>(checker.getTypeAtLocation), assertTypesEquivalent, boxDeclaration.name), parityCase("Checker", "getTypeAtLocation", checker.getTypeAtLocation, assertTypeArraysEquivalent, [boxDeclaration.name, combineDeclaration.name!]), parityCase("Checker", "getSignaturesOfType", checker.getSignaturesOfType, assertSignatureArraysEquivalent, checker.getTypeAtLocation(combineDeclaration.name!), SignatureKind.Call), @@ -1742,7 +1739,6 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => parityCase("Printer", "printNode", printer.printNode, assertDeepEquivalent, combineDeclaration, { preserveSourceNewlines: true }), parityCase("Printer", "printFile", printer.printFile, assertDeepEquivalent, indexFile, { preserveSourceNewlines: true }), - parityCase("SnapshotInternalAPI", "formatNodeForInsertion", snapshot.internal.formatNodeForInsertion, assertDeepEquivalent, combineDeclaration, "/src/index.ts", combineDeclaration.pos), parityCase("NodeHandle", "resolve", nodeHandle.resolve, assertOptionalNodesEquivalent), parityCase("NodeHandle", "resolve", nodeHandle.resolve, assertOptionalNodesEquivalent, project), @@ -1804,8 +1800,8 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => const snapshotGeneratorAPI = spawnAPI(parityFiles); const snapshotSyncAPI = spawnAPI(parityFiles); try { - const generatorBase = snapshotGeneratorAPI.batch(snapshotGeneratorAPI.createSnapshot.gen({ openProject: "/tsconfig.json" }))[0]; - const syncBase = snapshotSyncAPI.createSnapshot({ openProject: "/tsconfig.json" }); + const generatorBase = snapshotGeneratorAPI.batch(snapshotGeneratorAPI.createSnapshot.gen({ openProjects: ["/tsconfig.json"] }))[0]; + const syncBase = snapshotSyncAPI.createSnapshot({ openProjects: ["/tsconfig.json"] }); const generatorUpdated = snapshotGeneratorAPI.batch(generatorBase.update.gen({}))[0]; const syncUpdated = syncBase.update({}); assertSnapshotsEquivalent(generatorUpdated, syncUpdated, "Snapshot.update"); @@ -1817,7 +1813,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => } const destructiveAPI = spawnAPI(parityFiles); - const disposableSnapshot = destructiveAPI.batch(destructiveAPI.createSnapshot.gen({ openProject: "/tsconfig.json" }))[0]; + const disposableSnapshot = destructiveAPI.batch(destructiveAPI.createSnapshot.gen({ openProjects: ["/tsconfig.json"] }))[0]; destructiveAPI.batch(disposableSnapshot.dispose.gen()); assert.equal(disposableSnapshot.isDisposed(), true); assert.equal(disposableSnapshot.dispose(), undefined); @@ -1838,7 +1834,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => assertPublicGeneratorCoverage([ { name: "API", value: api }, { name: "API", value: api.constructor as object, own: true }, - { name: "InternalAPI", value: api.internal }, + { name: "DebugHandlers", value: api.debug }, { name: "Snapshot", value: snapshot }, { name: "ModuleResolver", value: moduleResolver }, { name: "Project", value: project }, @@ -1846,7 +1842,6 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => { name: "Program", value: program }, { name: "Checker", value: checker }, { name: "Printer", value: printer }, - { name: "SnapshotInternalAPI", value: snapshot.internal }, { name: "NodeHandle", value: nodeHandle }, { name: "Symbol", value: combineSymbol }, { name: "Type", value: interfaceType }, diff --git a/packages/typescript/test/sync/api.bench.ts b/packages/typescript/test/sync/api.bench.ts index 08f1fb4ea8d8b..ccb3bea1ab983 100644 --- a/packages/typescript/test/sync/api.bench.ts +++ b/packages/typescript/test/sync/api.bench.ts @@ -10,12 +10,12 @@ import { type Node, type SourceFile, SyntaxKind, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { API, type Project, type Snapshot, -} from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/sync"; import { writeFileSync } from "node:fs"; import inspector from "node:inspector"; import path from "node:path"; @@ -204,7 +204,7 @@ export function runBenchmarks(options?: { filter?: string; singleIteration?: boo } function loadSnapshot() { - snapshot = api.createSnapshot({ openProject: "tsc/testdata/fixtures/compiler/tsconfig.json" }); + snapshot = api.createSnapshot({ openProjects: ["tsc/testdata/fixtures/compiler/tsconfig.json"] }); project = snapshot.getProjects()[0]; } diff --git a/packages/typescript/test/sync/api.test.ts b/packages/typescript/test/sync/api.test.ts index b9f69d2e14aba..dbe34fb1b2d4b 100644 --- a/packages/typescript/test/sync/api.test.ts +++ b/packages/typescript/test/sync/api.test.ts @@ -49,7 +49,7 @@ import { SyntaxKind, tryGetAmbientModuleNameFromSymbolName, unescapeLeadingUnderscores, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { cloneNode, createArrayTypeNode, @@ -66,21 +66,21 @@ import { createVariableDeclaration, createVariableDeclarationList, createVariableStatement, -} from "@typescript/typescript/unstable/ast/factory"; -import { visitEachChild } from "@typescript/typescript/unstable/ast/visitor"; +} from "@typescript/typescript/ast/factory"; +import { visitEachChild } from "@typescript/typescript/ast/visitor"; import { createFileSystem, createFileSystemLayer, createFileSystemWithLib, type FileSystemCallbacks, serverFS, -} from "@typescript/typescript/unstable/fs"; +} from "@typescript/typescript/fs"; import { rootedDirectoryPathFromPath, rootedFilePathFromPath, toRootedDirectoryPath, toRootedFilePath, -} from "@typescript/typescript/unstable/path"; +} from "@typescript/typescript/path"; import { API, type BigIntLiteralType, @@ -132,7 +132,7 @@ import { type TypeReference, type UnionOrIntersectionType, type UserPreferences, -} from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/sync"; import assert from "node:assert"; import { globSync } from "node:fs"; import { resolve } from "node:path"; @@ -576,6 +576,7 @@ describe("API", { concurrency }, () => { const symbol = request; assert.ok(symbol); assert.strictEqual(cache.symbolsByDeclarationNodeIndex.get(index), symbol); + // @ts-ignore -- Internal symbol identity is exercised by source tests. assert.strictEqual(cache.symbolsById.get(symbol.reference.id), symbol); assert.equal(cache.declarationSymbolRequests.has(index), false); api.clearSourceFileCache(); @@ -739,7 +740,7 @@ describe("API", { concurrency }, () => { ], }); assert.equal(snapshot.getProjects().length, 2); - assert.deepEqual(snapshot.getProjects().map(project => project.rootFiles), [["/src/a.ts"], ["/src/b.ts"]]); + assert.deepEqual(snapshot.getProjects().map(project => project.parsedCommandLine.fileNames), [["/src/a.ts"], ["/src/b.ts"]]); assert.equal(snapshot.operation.createdPrograms!.length, 2); for (const program of snapshot.operation.createdPrograms!) { const syntheticProjectId: SyntheticProjectId = program.id; @@ -1483,6 +1484,7 @@ describe("BuildOrchestrator", () => { const { api: disposableApi } = spawnAPIWithFS({ ...files }); using api = disposableApi; const options = api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. using orchestrator = api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/", ...options }, @@ -1500,10 +1502,12 @@ describe("BuildOrchestrator", () => { test("api.close disposes all build orchestrators", () => { const { api } = spawnAPIWithFS({ ...files }); const options = api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator1 = api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/", ...options }, ); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator2 = api.createBuildOrchestrator( ["/b/tsconfig.json"], { cwd: "/", ...options }, @@ -1537,6 +1541,7 @@ describe("BuildOrchestrator", () => { traceResolution: false, }, }; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/a/tsconfig.json", "/b/tsconfig.json"], defaultOptions, @@ -1557,6 +1562,7 @@ describe("BuildOrchestrator", () => { "/a/src/index.ts": source, }); using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/" }, @@ -1583,6 +1589,7 @@ describe("BuildOrchestrator", () => { const { api: disposableApi } = spawnAPIWithFS({ ...files }); using api = disposableApi; const options = api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/", ...options }, @@ -1653,6 +1660,7 @@ describe("BuildOrchestrator", () => { "/a/dist/index.js": `export const a = 1;`, }); using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/a/tsconfig.json"], { cwd: "/" }, @@ -1674,6 +1682,7 @@ describe("BuildOrchestrator", () => { test("rebuilds projects after multiple file system changes", () => { const { api: disposableApi, fs } = spawnAPIWithFS({ ...files }); using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/a/tsconfig.json", "/b/tsconfig.json"], { cwd: "/" }, @@ -1703,6 +1712,7 @@ describe("BuildOrchestrator", () => { test("clean removes build outputs", () => { const { api: disposableApi, fs } = spawnAPIWithFS({ ...files }); using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1721,6 +1731,7 @@ describe("BuildOrchestrator", () => { test("builds and cleans selected projects after file system changes", () => { const { api: disposableApi, fs } = spawnAPIWithFS({ ...files }); using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1764,6 +1775,7 @@ describe("BuildOrchestrator", () => { }); using api = disposableApi; const options = api.parseCommandLine([]); + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1780,6 +1792,7 @@ describe("BuildOrchestrator", () => { ...files, }); using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/c/tsconfig.json"], { cwd: "/" }, @@ -1819,6 +1832,7 @@ describe("BuildOrchestrator", () => { path => writes.push(path), ); using api = disposableApi; + // @ts-ignore -- Internal API exercised by source tests. const orchestrator = api.createBuildOrchestrator( ["/c/tsconfig.json", "/d/tsconfig.json"], { cwd: "/" }, @@ -1854,7 +1868,7 @@ describe("Checker - getImmediateAliasedSymbol", { concurrency }, () => { "/src/main.ts": `import { foo } from "./foo";\nexport const usage = foo;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `import { foo } from "./foo";`.indexOf("foo }"); const aliasSymbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -1882,7 +1896,7 @@ test(); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -1907,7 +1921,7 @@ describe("Snapshot", { concurrency }, () => { test("createSnapshot returns snapshot with projects", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); assert.ok(snapshot); assert.ok(snapshot.id); assert.ok(snapshot.getProjects().length > 0); @@ -1920,19 +1934,17 @@ describe("Snapshot", { concurrency }, () => { "/tsconfig.json": JSON.stringify({ compileOnSave: true }), }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; assert.deepEqual(project.parsedCommandLine.fileNames, ["/src/index.ts", "/src/foo.ts"]); assert.deepEqual(project.parsedCommandLine.options, { configFilePath: "/tsconfig.json" }); assert.equal(project.parsedCommandLine.compileOnSave, true); - assert.deepEqual(project.rootFiles, project.parsedCommandLine.fileNames); - assert.deepEqual(project.compilerOptions, project.parsedCommandLine.options); }); test("getSymbolAtPosition", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/index.ts", 9); assert.ok(symbol); @@ -1943,7 +1955,7 @@ describe("Snapshot", { concurrency }, () => { test("getSymbolAtLocation", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -1961,7 +1973,7 @@ describe("Snapshot", { concurrency }, () => { test("getSymbolOfSourceFile", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const moduleSymbol = project.checker.getSymbolOfSourceFile("/src/foo.ts"); assert.ok(moduleSymbol); @@ -1975,7 +1987,7 @@ describe("Snapshot", { concurrency }, () => { "/src/script.ts": `const x = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolOfSourceFile("/src/script.ts"); assert.equal(symbol, undefined); @@ -1984,7 +1996,7 @@ describe("Snapshot", { concurrency }, () => { test("getSymbolOfSourceFile batched", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbols = project.checker.getSymbolOfSourceFile(["/src/index.ts", "/src/foo.ts"]); assert.equal(symbols.length, 2); @@ -1996,7 +2008,7 @@ describe("Snapshot", { concurrency }, () => { test("getTypeOfSymbol", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/index.ts", 9); assert.ok(symbol); @@ -2023,7 +2035,7 @@ describe("Snapshot", { concurrency }, () => { }); // when `"exactOptionalPropertyTypes": true` - const snapshot1 = api.createSnapshot({ openProject: "/tsconfig-one.json" }); + const snapshot1 = api.createSnapshot({ openProjects: ["/tsconfig-one.json"] }); const project1 = snapshot1.getConfiguredProject("/tsconfig-one.json")!; const type1 = project1.checker.getTypeAtPosition("/src/index.ts", 7); assert.ok(type1); @@ -2040,7 +2052,7 @@ describe("Snapshot", { concurrency }, () => { assert.ok(propertyType2.flags & TypeFlags.String); // when `"exactOptionalPropertyTypes": false` - const snapshot2 = api.createSnapshot({ openProject: "/tsconfig-two.json" }); + const snapshot2 = api.createSnapshot({ openProjects: ["/tsconfig-two.json"] }); const project2 = snapshot2.getConfiguredProject("/tsconfig-two.json")!; const type2 = project2.checker.getTypeAtPosition("/src/index.ts", 7); assert.ok(type2); @@ -2066,7 +2078,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `export const foo = 1;\n`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/foo.ts", "export const ".length); assert.ok(symbol); @@ -2084,7 +2096,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `export const foo = 1;\nexport const bar = 2;\n`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const foo = project.checker.getSymbolAtPosition("/src/foo.ts", "export const ".length); const bar = project.checker.getSymbolAtPosition("/src/foo.ts", "export const foo = 1;\nexport const ".length); @@ -2107,7 +2119,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/outside/src/foo.ts": `export const foo = 1;\n`, }); try { - const snapshot = api.createSnapshot({ openProject: "/outside/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/outside/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/outside/tsconfig.json")!; const foo = project.checker.getSymbolAtPosition("/outside/src/foo.ts", "export const ".length); assert.ok(foo); @@ -2131,7 +2143,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `export const foo = 1;\nexport const bar = 2;\n`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const bar = project.checker.getSymbolAtPosition("/src/foo.ts", "export const foo = 1;\nexport const ".length); assert.ok(bar); @@ -2151,7 +2163,7 @@ describe("LanguageService - imports", { concurrency }, () => { "/src/foo.ts": `const local = 1;\n`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/foo.ts", "const ".length); assert.ok(symbol); @@ -2166,7 +2178,7 @@ describe("LanguageService - imports", { concurrency }, () => { test("getImportAdderEdits rejects invalid actions", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/foo.ts", 13); assert.ok(symbol); @@ -2179,6 +2191,7 @@ describe("LanguageService - imports", { concurrency }, () => { () => project.languageService.getImportAdderEdits("/src/index.ts", [{ kind: "importSymbol", + // @ts-ignore -- Internal symbol identity is exercised by source tests. symbol: { ...symbol, reference: { ...symbol.reference, id: 999_999_999 } }, } as unknown as ImportAdderAction]), /symbol handle \d+ not found/, @@ -2194,7 +2207,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // Position right after "obj." — member completion trigger const pos = src.indexOf("obj.") + "obj.".length; @@ -2213,7 +2226,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("obj.") + "obj.".length; const completions = project.languageService.getCompletionsAtPosition("/src/main.ts", pos, { triggerCharacter: "." }); @@ -2228,7 +2241,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": `export {};`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const completions = project.languageService.getCompletionsAtPosition("/src/does-not-exist.ts", 0); assert.equal(completions, undefined, "Expected undefined for non-existent file"); @@ -2241,7 +2254,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("obj.") + "obj.".length; const completions = project.languageService.getCompletionsAtPosition("/src/main.ts", pos, { triggerCharacter: ".", includeSymbol: true }); @@ -2261,7 +2274,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { }); const unprepared = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], userPreferences: { includeCompletionsForModuleExports: true } satisfies UserPreferences, }); const unpreparedProject = unprepared.getConfiguredProject("/tsconfig.json")!; @@ -2282,7 +2295,7 @@ describe("LanguageService - getCompletionsAtPosition", { concurrency }, () => { }); const snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], userPreferences: { includeCompletionsForModuleExports: false } satisfies UserPreferences, }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; @@ -2308,7 +2321,7 @@ describe("LanguageService - getReferencedSymbolsForNode", { concurrency }, () => "/src/index.ts": `function greet(name: string) { return name; }\ngreet("world");`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2330,7 +2343,7 @@ describe("LanguageService - getSignatureUsage", { concurrency }, () => { "/src/index.ts": `function greet(name: string) { return name; }\ngreet("world");`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2350,7 +2363,7 @@ describe("Checker - getApparentType", { concurrency }, () => { "/src/main.ts": `export const x = "hello" as const;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `export const x = "hello" as const;`.indexOf("x ="); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -2388,7 +2401,7 @@ class QuotaExceededError extends TaggedError("QuotaExceededError")<{ export type Result = RateLimitError | (RateLimitError & QuotaExceededError);`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -2410,7 +2423,7 @@ describe("Checker - getMemberInModuleExports", { concurrency }, () => { "/src/index.ts": `export const direct = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2431,7 +2444,7 @@ describe("SourceFile", { concurrency }, () => { "/outside/src/index.ts": "export const value = 1;", }); - const snapshot = api.createSnapshot({ openProject: "/outside/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/outside/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/outside/tsconfig.json")!.program; const absolute = program.getSourceFile("/outside/src/index.ts"); const relative = program.getSourceFile("src/index.ts"); @@ -2443,7 +2456,7 @@ describe("SourceFile", { concurrency }, () => { test("getSourceFile rejects invalid document identifiers", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/tsconfig.json")!.program; const document = { fileName: "/src/index.ts" } as unknown as DocumentIdentifier; @@ -2470,7 +2483,7 @@ describe("SourceFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const bar: number;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const fileNames = project.program.getSourceFileNames(); assert.deepEqual(fileNames, [ @@ -2492,7 +2505,7 @@ describe("SourceFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const bar: number;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const program = project.program; @@ -2529,7 +2542,7 @@ describe("SourceFile", { concurrency }, () => { "/esm/index.ts": `export const m = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const program = snapshot.getConfiguredProject("/tsconfig.json")!.program; const mts = program.getSourceFile("/src/esm.mts"); @@ -2555,7 +2568,7 @@ describe("SourceFile", { concurrency }, () => { test("file properties", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); @@ -2567,7 +2580,7 @@ describe("SourceFile", { concurrency }, () => { test("extended data", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); @@ -2601,7 +2614,7 @@ describe("SourceFile", { concurrency }, () => { "/input.ts": `let arrow = () => {}`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/input.ts"); @@ -2636,7 +2649,7 @@ describe("NodeArray", { concurrency }, () => { "/src/main.ts": `declare function foo(...args: any): void;\nfoo("a", "b",);\nfoo("a", "b");`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -2657,7 +2670,7 @@ describe("API objects", { concurrency }, () => { "/src/3.ts": `"\\ud800a\\udc00"`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const expectedTexts = new Map([ ["/src/1.ts", "😃"], @@ -2684,7 +2697,7 @@ describe("API objects", { concurrency }, () => { "/src/index.ts": "`\\ud800${0}\\udc00`", }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -2709,7 +2722,7 @@ describe("API objects", { concurrency }, () => { test("Object equality", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // Same symbol returned from same snapshot's checker assert.strictEqual( @@ -2721,7 +2734,7 @@ describe("API objects", { concurrency }, () => { test("Snapshot dispose", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/index.ts", 9); assert.ok(symbol); @@ -2745,8 +2758,8 @@ describe("Multiple snapshots", { concurrency }, () => { test("two snapshots work independently", () => { using api = spawnAPI(); - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); - const snap2 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const snap2 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Both can fetch source files const sf1 = snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); @@ -2769,7 +2782,7 @@ describe("Multiple snapshots", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); using api = disposableAPI; - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Verify initial state const sf1 = snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -2779,7 +2792,7 @@ describe("Multiple snapshots", { concurrency }, () => { // Mutate the file and create a new snapshot with the change fs.writeFile!(toRootedFilePath("/src/foo.ts", undefined), `export const foo = "changed";`); const snap2 = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); @@ -2800,7 +2813,7 @@ describe("Multiple snapshots", { concurrency }, () => { snap2.dispose(); // Both are disposed, new snapshot works fine with latest content - const snap3 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap3 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf3 = snap3.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); assert.ok(sf3); assert.equal(sf3.text, `export const foo = "changed";`); @@ -2810,12 +2823,12 @@ describe("Multiple snapshots", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); using api = disposableAPI; - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Add a brand new file fs.writeFile!(toRootedFilePath("/src/bar.ts", undefined), `export const bar = true;`); const snap2 = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { created: ["/src/bar.ts"] }, }); @@ -2832,7 +2845,7 @@ describe("Multiple snapshots", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); using api = disposableAPI; - api.createSnapshot({ openProject: "/tsconfig.json" }); + api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const versions = [ `export const foo = 1;`, @@ -2843,7 +2856,7 @@ describe("Multiple snapshots", { concurrency }, () => { for (const version of versions) { fs.writeFile!(toRootedFilePath("/src/foo.ts", undefined), version); const snap = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); const sf = snap.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -2951,7 +2964,7 @@ describe("Source file caching", { concurrency }, () => { test("same file from same snapshot returns cached object", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sf1 = project.program.getSourceFile("/src/index.ts"); const sf2 = project.program.getSourceFile("/src/index.ts"); @@ -2962,8 +2975,8 @@ describe("Source file caching", { concurrency }, () => { test("same file from two snapshots (same content) returns cached object", () => { using api = spawnAPI(); - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); - const snap2 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const snap2 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Fetch from snap1 first (populates cache), then snap2 (cache hit via hash) const sf1 = snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); const sf2 = snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); @@ -2977,7 +2990,7 @@ describe("Source file caching", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); using api = disposableAPI; - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf1 = snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); assert.ok(sf1); assert.equal(sf1.text, `export const foo = 42;`); @@ -2987,7 +3000,7 @@ describe("Source file caching", { concurrency }, () => { // Notify the server about the change const snap2 = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); const sf2 = snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -3002,7 +3015,7 @@ describe("Source file caching", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); using api = disposableAPI; - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf1 = snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); assert.ok(sf1); @@ -3011,7 +3024,7 @@ describe("Source file caching", { concurrency }, () => { // Notify the server about the change to foo.ts only const snap2 = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/foo.ts"] }, }); const sf2 = snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); @@ -3024,12 +3037,12 @@ describe("Source file caching", { concurrency }, () => { test("disposing the source snapshot releases its cache entries", () => { using api = spawnAPI(); - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); // Fetch from snap1 to populate cache const sf1 = snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/index.ts"); assert.ok(sf1); - const snap2 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap2 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); snap1.dispose(); @@ -3042,7 +3055,7 @@ describe("Source file caching", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS(); using api = disposableAPI; - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sf1 = snap1.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); assert.ok(sf1); assert.equal(sf1.text, `export const foo = 42;`); @@ -3052,7 +3065,7 @@ describe("Source file caching", { concurrency }, () => { // Use invalidateAll to force re-fetch const snap2 = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { invalidateAll: true }, }); const sf2 = snap2.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/foo.ts"); @@ -3070,7 +3083,7 @@ describe("Source file caching", { concurrency }, () => { using api = disposableAPI; // Snapshot 1: get a node and verify getContextualType works - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const proj1 = snap1.getConfiguredProject("/tsconfig.json")!; const sf1 = proj1.program.getSourceFile("/src/main.ts"); @@ -3090,7 +3103,7 @@ describe("Source file caching", { concurrency }, () => { // Snapshot 2: change a different file fs.writeFile!(toRootedFilePath("/src/other.ts", undefined), `export const x = 2;`); const snap2 = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/other.ts"] }, }); const proj2 = snap2.getConfiguredProject("/tsconfig.json")!; @@ -3119,7 +3132,7 @@ describe("Snapshot disposal", { concurrency }, () => { test("dispose is idempotent", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstDispose = snapshot.dispose(); const secondDispose = snapshot.dispose(); assert.strictEqual(firstDispose, secondDispose); @@ -3134,7 +3147,7 @@ describe("Snapshot disposal", { concurrency }, () => { const api = spawnAPI(); let snapshot: Snapshot; { - using disposableSnapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + using disposableSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); snapshot = disposableSnapshot; } assert.ok(snapshot.isDisposed()); @@ -3144,8 +3157,8 @@ describe("Snapshot disposal", { concurrency }, () => { test("api.close disposes all active snapshots", () => { const api = spawnAPI(); - const snap1 = api.createSnapshot({ openProject: "/tsconfig.json" }); - const snap2 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snap1 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const snap2 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); assert.ok(!snap1.isDisposed()); assert.ok(!snap2.isDisposed()); api.close(); @@ -3303,7 +3316,7 @@ export class MyClass { test("getTypeAtPosition", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const xPos = src.indexOf("x = 42"); @@ -3315,7 +3328,7 @@ export class MyClass { test("getTypeAtPosition batched", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const xPos = src.indexOf("x = 42"); @@ -3329,7 +3342,7 @@ export class MyClass { test("getTypeAtLocation", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -3356,7 +3369,7 @@ const c = obj.b.c; using api = spawnAPI(files); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -3402,12 +3415,12 @@ export class Cache { using api = spawnAPI(files); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); - let callNode: import("@typescript/typescript/unstable/ast").CallExpression | undefined; + let callNode: import("@typescript/typescript/ast").CallExpression | undefined; sourceFile.forEachChild(function visit(node) { if (isCallExpression(node)) { const text = sourceFile.text.slice(node.pos, node.end).trim(); @@ -3439,7 +3452,7 @@ export class Cache { test("getSignaturesOfType - call signatures", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const addPos = src.indexOf("add("); @@ -3464,7 +3477,7 @@ export class Cache { test("getApparentProperties includes CallableFunction members", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3483,7 +3496,7 @@ export class Cache { collectTiming: true, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3528,7 +3541,7 @@ export class Cache { test("getSignaturesOfType - construct signatures", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const classPos = src.indexOf("MyClass"); @@ -3545,7 +3558,7 @@ export class Cache { test("Signature declaration can be resolved", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const addPos = src.indexOf("add("); @@ -3596,7 +3609,7 @@ export class Cache { "/src/main.ts": mainFile, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const liftPos = mainFile.indexOf("lift"); const type = project.checker.getTypeAtPosition("/src/main.ts", liftPos); @@ -3616,7 +3629,7 @@ export class Cache { test("Signature.getParameters() returns parameter symbols with correct names", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3636,7 +3649,7 @@ export class Cache { test("Signature.getThisParameter() returns undefined when no explicit this parameter", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3656,7 +3669,7 @@ export class Cache { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("foo(")); assert.ok(symbol); @@ -3673,7 +3686,7 @@ export class Cache { test("Signature.getTarget() returns undefined for a non-instantiated signature", () => { using api = spawnAPI(checkerFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = checkerFiles["/src/main.ts"]; const symbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("add(")); @@ -3696,7 +3709,7 @@ export class Cache { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -3730,7 +3743,7 @@ export const value = 1; test("getMembers returns class members", () => { using api = spawnAPI(symbolFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = symbolFiles["/src/mod.ts"]; const animalPos = src.indexOf("Animal"); @@ -3746,7 +3759,7 @@ export const value = 1; test("getExports returns module exports via sourceFile symbol", () => { using api = spawnAPI(symbolFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/mod.ts"); assert.ok(sourceFile); @@ -3762,7 +3775,7 @@ export const value = 1; test("getParent returns containing symbol", () => { using api = spawnAPI(symbolFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = symbolFiles["/src/mod.ts"]; const namePos = src.indexOf("name:"); @@ -3777,7 +3790,7 @@ export const value = 1; test("checkFlags is typed as CheckFlags", () => { using api = spawnAPI(symbolFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/mod.ts", symbolFiles["/src/mod.ts"].indexOf("Animal")); assert.ok(symbol); @@ -3787,7 +3800,7 @@ export const value = 1; test("binder symbols are shared by file before the AST is fetched", () => { using api = spawnAPI(symbolFiles, { collectTiming: true }); - const firstSnapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; const secondSnapshot = firstSnapshot.update({}); const secondProject = secondSnapshot.getConfiguredProject("/tsconfig.json")!; @@ -3809,7 +3822,7 @@ export const value = 1; test("file-owned symbol properties do not require a snapshot or project", () => { using api = spawnAPI(symbolFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/mod.ts"); assert.ok(sourceFile); @@ -3833,7 +3846,7 @@ export const value = 1; "/src/a.ts": `namespace Merged { export const a = 1; }`, "/src/b.ts": `namespace Merged { export const b = 1; }`, }); - const firstSnapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; const secondSnapshot = firstSnapshot.update({}); const secondProject = secondSnapshot.getConfiguredProject("/tsconfig.json")!; @@ -3914,7 +3927,7 @@ export const value = 1; "/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true }, files: ["/src/box.ts"] }), "/src/box.ts": source, }, { collectTiming: true }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const box = project.checker.getSymbolAtPosition("/src/box.ts", source.indexOf("Box")); assert.ok(box); @@ -3935,7 +3948,7 @@ export const value = 1; "/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true }, files: ["/src/box.ts"] }), "/src/box.ts": source, }); - const firstSnapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; // Create the second snapshot before the first symbol response populates // the client cache. This ensures its registry has no direct retain on @@ -3972,7 +3985,7 @@ export const value = 1; test("file-owned declarations resolve without the snapshot that observed them", () => { using api = spawnAPI(symbolFiles); - const firstSnapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const firstProject = firstSnapshot.getConfiguredProject("/tsconfig.json")!; // Keeps the server AST alive after the observing snapshot is disposed. using _secondSnapshot = firstSnapshot.update({}); @@ -3988,12 +4001,12 @@ export const value = 1; test("file-owned symbols are accepted by later checkers while their file is unchanged", () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...symbolFiles, "/src/other.ts": `export const other = 1;` }); using api = disposableAPI; - const firstSnapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const animal = firstSnapshot.getConfiguredProject("/tsconfig.json")!.checker.getSymbolAtPosition("/src/mod.ts", symbolFiles["/src/mod.ts"].indexOf("Animal")); assert.ok(animal); fs.writeFile!(toRootedFilePath("/src/other.ts", undefined), `export const other = 2;`); - const secondSnapshot = api.createSnapshot({ openProject: "/tsconfig.json", fileNotifications: { changed: ["/src/other.ts"] } }); + const secondSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/other.ts"] } }); const type = secondSnapshot.getConfiguredProject("/tsconfig.json")!.checker.getTypeOfSymbol(animal); assert.ok(type); assert.strictEqual(type.getSymbol(), animal); @@ -4002,12 +4015,12 @@ export const value = 1; test("file-owned symbols are rejected by checkers whose program has a different version of their file", () => { const { api: disposableAPI, fs } = spawnAPIWithFS(symbolFiles); using api = disposableAPI; - const firstSnapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const firstSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const animal = firstSnapshot.getConfiguredProject("/tsconfig.json")!.checker.getSymbolAtPosition("/src/mod.ts", symbolFiles["/src/mod.ts"].indexOf("Animal")); assert.ok(animal); fs.writeFile!(toRootedFilePath("/src/mod.ts", undefined), `${symbolFiles["/src/mod.ts"]}\nexport const added = 2;`); - const secondSnapshot = api.createSnapshot({ openProject: "/tsconfig.json", fileNotifications: { changed: ["/src/mod.ts"] } }); + const secondSnapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"], fileNotifications: { changed: ["/src/mod.ts"] } }); const secondProject = secondSnapshot.getConfiguredProject("/tsconfig.json")!; assert.throws(() => secondProject.checker.getTypeOfSymbol(animal), /source file is not part of the requested program/); }); @@ -4025,7 +4038,7 @@ export const instance: Foo = new Foo(); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Foo {\n x: number = 0;\n}\nexport const instance: Foo = new Foo();\n`; const instancePos = src.indexOf("instance"); @@ -4060,7 +4073,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; }; function getTypeAtName(api: API, name: string) { - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = typeFiles["/src/types.ts"]; const pos = src.indexOf(name); @@ -4125,7 +4138,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // `string` is neither a union/intersection nor a template literal type, @@ -4148,7 +4161,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("IndexType.getTarget() returns the target type", () => { using api = spawnAPI(typeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.resolveName("KeyOf", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4164,7 +4177,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("IndexedAccessType.getObjectType() and getIndexType()", () => { using api = spawnAPI(typeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.resolveName("Lookup", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4182,7 +4195,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("ConditionalType.getCheckType() and getExtendsType()", () => { using api = spawnAPI(typeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.resolveName("Cond", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4200,7 +4213,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("ConditionalType.getTrueType() and getFalseType()", () => { using api = spawnAPI(typeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.resolveName("Cond", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4222,7 +4235,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("MappedType exposes its component types", () => { using api = spawnAPI(typeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.resolveName("Mapped", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4239,7 +4252,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("MappedType returned as a union constituent exposes its component types", () => { using api = spawnAPI(typeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.resolveName("MappedUnion", SymbolFlags.TypeAlias, { document: "/src/types.ts", position: 0 }); assert.ok(symbol); @@ -4269,7 +4282,7 @@ export const tuple: readonly [number, string?, ...boolean[]] = [1]; test("StringMappingType.getTarget() returns the mapped type", () => { using api = spawnAPI(typeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = typeFiles["/src/types.ts"]; const pos = src.indexOf("Upper"); @@ -4299,7 +4312,7 @@ array([]); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -4351,7 +4364,7 @@ export function gh1449(a: T): T { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -4389,7 +4402,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getAnyType returns a type with Any flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getAnyType(); assert.ok(type); @@ -4399,7 +4412,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getStringType returns a type with String flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getStringType(); assert.ok(type); @@ -4409,7 +4422,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNumberType returns a type with Number flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getNumberType(); assert.ok(type); @@ -4419,7 +4432,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getBooleanType returns a type with Boolean flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getBooleanType(); assert.ok(type); @@ -4429,7 +4442,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getVoidType returns a type with Void flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getVoidType(); assert.ok(type); @@ -4439,7 +4452,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getUndefinedType returns a type with Undefined flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getUndefinedType(); assert.ok(type); @@ -4449,7 +4462,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNullType returns a type with Null flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getNullType(); assert.ok(type); @@ -4459,7 +4472,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNeverType returns a type with Never flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getNeverType(); assert.ok(type); @@ -4469,7 +4482,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getUnknownType returns a type with Unknown flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getUnknownType(); assert.ok(type); @@ -4479,7 +4492,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getBigIntType returns a type with BigInt flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getBigIntType(); assert.ok(type); @@ -4489,7 +4502,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getESSymbolType returns a type with ESSymbol flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getESSymbolType(); assert.ok(type); @@ -4499,7 +4512,7 @@ describe("Checker - intrinsic type getters", { concurrency }, () => { test("getNonPrimitiveType returns a type with NonPrimitive flag", () => { using api = spawnAPI(intrinsicFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const type = project.checker.getNonPrimitiveType(); assert.ok(type); @@ -4620,7 +4633,7 @@ describe("Checker - getBaseTypeOfLiteralType", { concurrency }, () => { "/src/main.ts": `export const x = 42;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const x = 42;`; const pos = src.indexOf("x ="); @@ -4640,7 +4653,7 @@ describe("Checker - getBaseTypeOfLiteralType", { concurrency }, () => { "/src/main.ts": `export const s = "hello";`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const s = "hello";`; const pos = src.indexOf("s "); @@ -4665,7 +4678,7 @@ foo(42); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); @@ -4675,7 +4688,7 @@ foo(42); // statement[1] = foo(42); which is an ExpressionStatement -> CallExpression const callStmt = sourceFile.statements[1]; assert.ok(callStmt); - let numLiteral: import("@typescript/typescript/unstable/ast").Expression | undefined; + let numLiteral: import("@typescript/typescript/ast").Expression | undefined; callStmt.forEachChild(function visit(node) { if (isCallExpression(node)) { // First argument @@ -4704,7 +4717,7 @@ export function check(x: string | number) { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport function check(x: string | number) {\n if (typeof x === "string") {\n return x;\n }\n return x;\n}\n`; @@ -4727,7 +4740,7 @@ export function check(x: string | number) { const funcDecl = sourceFile.statements[0]; assert.ok(funcDecl); // Walk to find the first "return x" — inside the if, x should be narrowed to string - let firstReturnX: import("@typescript/typescript/unstable/ast").Node | undefined; + let firstReturnX: import("@typescript/typescript/ast").Node | undefined; funcDecl.forEachChild(function visit(node) { if (isReturnStatement(node) && !firstReturnX) { // The expression of the return statement is the identifier "x" @@ -4755,7 +4768,7 @@ export const obj = { name }; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); @@ -4763,7 +4776,7 @@ export const obj = { name }; // Find the shorthand property assignment { name } // statement[1] = export const obj = { name }; - let shorthandNode: import("@typescript/typescript/unstable/ast").Node | undefined; + let shorthandNode: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (isShorthandPropertyAssignment(node)) { shorthandNode = node; @@ -4819,7 +4832,7 @@ describe("readFile callback semantics", { concurrency }, () => { const callbacks: FileSystemCallbacks = { ...fs, realpath }; using api = new API({ cwd: "/", fs: callbacks }); - using snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + using snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); assert.ok( (snapshot.getConfiguredProject("/tsconfig.json")!.program.getSourceFileNames()) .includes(toRootedFilePath("/node_modules/pkg/index.d.ts", undefined)), @@ -4852,7 +4865,7 @@ describe("readFile callback semantics", { concurrency }, () => { fs, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // 1. String content: virtual file is found @@ -4885,7 +4898,7 @@ describe("readFile callback semantics", { concurrency }, () => { fs: createVirtualFileSystem(files), useCaseSensitiveFileNames: false, }); - const program = (api.createSnapshot({ openProject: "/tsconfig.json" })).getConfiguredProject("/tsconfig.json")!.program; + const program = (api.createSnapshot({ openProjects: ["/tsconfig.json"] })).getConfiguredProject("/tsconfig.json")!.program; assert.ok(program.getSourceFile("/SRC/INDEX.TS")); } { @@ -4894,7 +4907,7 @@ describe("readFile callback semantics", { concurrency }, () => { fs: createVirtualFileSystem(files), useCaseSensitiveFileNames: true, }); - const program = (api.createSnapshot({ openProject: "/tsconfig.json" })).getConfiguredProject("/tsconfig.json")!.program; + const program = (api.createSnapshot({ openProjects: ["/tsconfig.json"] })).getConfiguredProject("/tsconfig.json")!.program; assert.equal(program.getSourceFile("/SRC/INDEX.TS"), undefined); } }); @@ -5014,7 +5027,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5039,7 +5052,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystemWithLib(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true }, files: ["src/main.ts"] }), "/src/main.ts": `export const values: Array = [];`, @@ -5113,7 +5126,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: { kind: "layer", files: { @@ -5146,7 +5159,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystemLayer([ ["/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true }, include: ["src/**/*.ts"] })], ["/src/from-cache.ts", `export const cache = true;`], @@ -5179,7 +5192,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); using snapshot = api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5220,7 +5233,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); using snapshot = api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5246,7 +5259,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true }, @@ -5302,7 +5315,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); let snapshot: Snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem([ ["/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true }, files: ["pkg/index.ts"] })], ["/pkg/index.ts", ""], @@ -5340,7 +5353,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { using snapshot = api.createSnapshot(); using replaced = snapshot.update({ ensurePrograms: true, - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem([ ["/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true }, files: ["memory.ts", "host.ts"] })], ["/memory.ts", `export const source = "memory";`], @@ -5356,7 +5369,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { cwd: fileURLToPath(new URL("../../../../", import.meta.url).toString()), }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem( Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true }, files: ["src/main.ts"] }), @@ -5408,7 +5421,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }, }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystem(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true, outDir: "/out", rootDir: "/src" }, files: ["src/main.ts"] }), "/src/main.ts": `export const value: number = 1;`, @@ -5438,7 +5451,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { fs: host, }); using snapshot = api.createSnapshot({ - openProject: "/tsconfig.json", + openProjects: ["/tsconfig.json"], fileSystem: createFileSystemLayer(Object.entries({ "/tsconfig.json": JSON.stringify({ compilerOptions: { noLib: true, outDir: "/out", rootDir: "/src" }, files: ["src/main.ts"] }), "/src/main.ts": `export const value: number = 1;`, @@ -5478,7 +5491,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { }); using snapshot = api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: { kind: "full", files: { @@ -5513,7 +5526,7 @@ describe("updateSnapshot file systems", { concurrency }, () => { fs: host, }); using snapshot = api.createSnapshot({ - openProject: "/project/tsconfig.json", + openProjects: ["/project/tsconfig.json"], fileSystem: createFileSystem([ ["/project/tsconfig.json", JSON.stringify({ compilerOptions: { noLib: true, moduleResolution: "node" }, files: ["index.ts"] })], ["/project/index.ts", `import { value } from "pkg"; export { value };`], @@ -5548,7 +5561,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const xs: number[] = [];`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const xs: number[] = [];`; const pos = src.indexOf("xs"); @@ -5566,7 +5579,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const xs: readonly number[] = [];`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const xs: readonly number[] = [];`; const pos = src.indexOf("xs"); @@ -5584,7 +5597,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const xs: Array = [];`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const xs: Array = [];`; const pos = src.indexOf("xs"); @@ -5602,7 +5615,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const tup: [number, string] = [1, "a"];`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const tup: [number, string] = [1, "a"];`; const pos = src.indexOf("tup"); @@ -5620,7 +5633,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const tup: readonly [number, string] = [1, "a"];`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const tup: readonly [number, string] = [1, "a"];`; const pos = src.indexOf("tup"); @@ -5638,7 +5651,7 @@ describe("Checker - isArrayType / isTupleType", { concurrency }, () => { "/src/main.ts": `export const str: string = "";`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const str: string = "";`; const pos = src.indexOf("str"); @@ -5665,7 +5678,7 @@ export type ReadonlyUser = Readonly; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -5691,7 +5704,7 @@ export type ReadonlyUser = Readonly; "/src/main.ts": `export const a = 1; export let b = 2;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const a = checker.getSymbolAtPosition("/src/main.ts", "export const ".length); const b = checker.getSymbolAtPosition("/src/main.ts", "export const a = 1; export let ".length); @@ -5725,7 +5738,7 @@ export type B = InstanceType; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -5749,7 +5762,7 @@ describe("Checker - getReturnTypeOfSignature", { concurrency }, () => { "/src/main.ts": `export function add(a: number, b: number): number { return a + b; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function add(a: number, b: number): number { return a + b; }`; const pos = src.indexOf("add("); @@ -5772,7 +5785,7 @@ describe("Checker - getRestTypeOfSignature", { concurrency }, () => { "/src/main.ts": `export function sum(...nums: number[]): number { return nums.reduce((a, b) => a + b, 0); }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function sum(...nums: number[]): number { return nums.reduce((a, b) => a + b, 0); }`; const pos = src.indexOf("sum("); @@ -5795,7 +5808,7 @@ describe("Checker - getTypePredicateOfSignature", { concurrency }, () => { "/src/main.ts": `export function isString(x: unknown): x is string { return typeof x === "string"; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function isString(x: unknown): x is string { return typeof x === "string"; }`; const pos = src.indexOf("isString("); @@ -5827,7 +5840,7 @@ export class Dog extends Animal { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Animal {\n isdog(): this is Dog { return this instanceof Dog; }\n}\nexport class Dog extends Animal {\n bark() {}\n}\n`; const pos = src.indexOf("isdog("); @@ -5848,7 +5861,7 @@ export class Dog extends Animal { "/src/main.ts": `export function assertIsString(x: unknown): asserts x is string { if (typeof x !== "string") throw new Error(); }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function assertIsString(x: unknown): asserts x is string { if (typeof x !== "string") throw new Error(); }`; const pos = src.indexOf("assertIsString("); @@ -5873,7 +5886,7 @@ export class Dog extends Animal { "/src/main.ts": `export function add(a: number, b: number): number { return a + b; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function add(a: number, b: number): number { return a + b; }`; const pos = src.indexOf("add("); @@ -5902,7 +5915,7 @@ export class Derived extends Base { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Base {\n x: number = 0;\n}\nexport class Derived extends Base {\n y: string = "";\n}\n`; const pos = src.indexOf("Derived"); @@ -5930,7 +5943,7 @@ export interface Dog extends Animal { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface Animal {\n name: string;\n}\nexport interface Dog extends Animal {\n bark(): void;\n}\n`; const pos = src.indexOf("Dog"); @@ -5956,7 +5969,7 @@ export type BoxOfString = Box; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -5986,7 +5999,7 @@ export const n: number = 0; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport class Base {\n x: number = 0;\n}\nexport class Derived extends Base {\n y: string = "";\n}\nexport const n: number = 0;\n`; @@ -6019,7 +6032,7 @@ declare const bad: ThisTypeDoesNotExist; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\ndeclare const good: string;\ndeclare const bad: ThisTypeDoesNotExist;\n`; @@ -6049,7 +6062,7 @@ export type Alias = typeof value; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport const value = 1;\nexport type Alias = typeof value;\n`; @@ -6074,7 +6087,7 @@ notCallable(); "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6108,7 +6121,7 @@ export const value = 1; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6136,7 +6149,7 @@ export const obj: { a: number } = { a: 1 }; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport const obj: { a: number } = { a: 1 };\n`; const objSymbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("obj")); @@ -6169,7 +6182,7 @@ export { x as '${maliciousName}' }; "/src/main.ts": source, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const typesFile = project.program.getSourceFile("/src/types.d.ts"); @@ -6243,7 +6256,7 @@ export const total = add(1, 2); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6305,7 +6318,7 @@ var measure = function (name) { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6340,7 +6353,7 @@ const cast = /** @type {number} */ (someValue); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6370,7 +6383,7 @@ export const answer = 42; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6398,7 +6411,7 @@ export const answer = 42; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6426,7 +6439,7 @@ const cast = /** @type {number} */ (someValue); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6452,7 +6465,7 @@ var measure = function (name) { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.js"); assert.ok(sourceFile); @@ -6488,7 +6501,7 @@ export function add(a: number, b: number): number { `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6520,7 +6533,7 @@ export declare const p: Person; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface Person {\n name: string;\n age: number;\n greet(): void;\n}\nexport declare const p: Person;\n`; const pos = src.indexOf("p: Person"); @@ -6549,7 +6562,7 @@ export declare const m: StringMap; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface StringMap {\n [key: string]: number;\n}\nexport declare const m: StringMap;\n`; const pos = src.indexOf("m: StringMap"); @@ -6578,7 +6591,7 @@ export declare const m: ReadonlyMap; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface ReadonlyMap {\n readonly [key: string]: number;\n}\nexport declare const m: ReadonlyMap;\n`; const pos = src.indexOf("m: ReadonlyMap"); @@ -6619,7 +6632,7 @@ export type Exported = number; test("exposes interface this types and checker operations", () => { using api = spawnAPI(files); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6662,7 +6675,7 @@ export type Exported = number; assert.notEqual(localSymbol.id, exportedSymbol.id); assert.strictEqual(project.checker.getExportSymbolOfSymbol(localSymbol), exportedSymbol); - let call: import("@typescript/typescript/unstable/ast").CallExpression | undefined; + let call: import("@typescript/typescript/ast").CallExpression | undefined; sourceFile.forEachChild(function visit(node) { if (isCallExpression(node) && sourceFile.text.slice(node.expression.pos, node.expression.end).trim() === "consume") { call = node; @@ -6688,7 +6701,7 @@ describe("Checker - getConstraintOfTypeParameter", { concurrency }, () => { "/src/main.ts": `export function identity(x: T): T { return x; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function identity(x: T): T { return x; }`; const pos = src.indexOf("identity<"); @@ -6713,7 +6726,7 @@ describe("Checker - TypeParameter getters", { concurrency }, () => { "/src/main.ts": `export function f(x: T): T { return x; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function f(x: T): T { return x; }`; const pos = src.indexOf("f<"); @@ -6742,7 +6755,7 @@ describe("Checker - TypeParameter getters", { concurrency }, () => { "/src/main.ts": `export function f(x: T): T { return x; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function f(x: T): T { return x; }`; const pos = src.indexOf("f<"); @@ -6768,7 +6781,7 @@ describe("Checker - getTypeArguments", { concurrency }, () => { "/src/main.ts": `export const arr: Array = [1, 2, 3];`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export const arr: Array = [1, 2, 3];`; const pos = src.indexOf("arr:"); @@ -6788,7 +6801,7 @@ describe("Checker - getTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // `string` is not a type reference. When getTypeArguments is reached @@ -6817,7 +6830,7 @@ describe("Checker - getBaseConstraintOfType", { concurrency }, () => { "/src/main.ts": `export function identity(x: T): T { return x; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `export function identity(x: T): T { return x; }`; const pos = src.indexOf("identity<"); @@ -6839,7 +6852,7 @@ describe("Checker - getBaseConstraintOfType", { concurrency }, () => { "/src/main.ts": `export const x: number = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `export const x: number = 1;`.indexOf("x:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -6864,7 +6877,7 @@ export declare const p: Person; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const src = `\nexport interface Person {\n name: string;\n age: number;\n}\nexport declare const p: Person;\n`; const pos = src.indexOf("p: Person"); @@ -6887,7 +6900,7 @@ describe("Checker - getConstantValue", { concurrency }, () => { "/src/main.ts": `export enum E { A = 1, B = 2 }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6918,7 +6931,7 @@ describe("Checker - getConstantValue", { concurrency }, () => { }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6944,7 +6957,7 @@ describe("Checker - getConstantValue", { concurrency }, () => { "/src/main.ts": `export enum Color { Red = "red" }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6966,7 +6979,7 @@ describe("Checker - getSignatureFromDeclaration", { concurrency }, () => { "/src/main.ts": `export function add(a: number, b: number): number { return a + b; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -6995,7 +7008,7 @@ export { value as renamed }; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7019,7 +7032,7 @@ describe("Checker - getAliasedSymbol", { concurrency }, () => { "/src/main.ts": `import { foo } from "./foo";\nexport const usage = foo;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = `import { foo } from "./foo";`.indexOf("foo }"); const aliasSymbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7044,7 +7057,7 @@ export class Standalone {} `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -7073,7 +7086,7 @@ export * from "./inner"; `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -7102,7 +7115,7 @@ function f() { test("returns symbols visible at a position", () => { using api = spawnAPI(scopeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = scopeFiles["/src/main.ts"].indexOf("return innerValue"); const symbols = project.checker.getSymbolsInScope( @@ -7119,7 +7132,7 @@ function f() { test("returns type symbols when asked for type meaning at a node", () => { using api = spawnAPI(scopeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); @@ -7134,7 +7147,7 @@ function f() { test("SymbolFlags.All includes both value and type meanings", () => { using api = spawnAPI(scopeFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = scopeFiles["/src/main.ts"].indexOf("return innerValue"); const symbols = project.checker.getSymbolsInScope( @@ -7163,7 +7176,7 @@ export function add(a: number, b: number): number { return a + b; } test("getDocumentationComment returns the leading comment text", () => { using api = spawnAPI(docFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = docFiles["/src/main.ts"].indexOf("add(a"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7176,7 +7189,7 @@ export function add(a: number, b: number): number { return a + b; } test("getJsDocTags returns structured tag name/text pairs", () => { using api = spawnAPI(docFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = docFiles["/src/main.ts"].indexOf("add(a"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7199,7 +7212,7 @@ describe("TypeParameter - isThisType", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // ": this {" — offset 2 past ': ' lands on 't' in the return-type 'this' const pos = src.indexOf(": this {") + 2; @@ -7217,7 +7230,7 @@ describe("TypeParameter - isThisType", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // Point to 'T' in the type parameter declaration '' — getTypeAtPosition // on a type annotation reference doesn't resolve to TypeParameter, but @@ -7239,7 +7252,7 @@ describe("Type - getAliasTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("x:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7258,7 +7271,7 @@ describe("Type - getAliasTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("p:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7278,7 +7291,7 @@ describe("Type - getAliasTypeArguments", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("arr:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7299,7 +7312,7 @@ describe("Type - getAliasSymbol", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("p:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7318,7 +7331,7 @@ describe("Type - getAliasSymbol", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("c:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7337,7 +7350,7 @@ describe("Type - getAliasSymbol", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("str:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7357,7 +7370,7 @@ describe("IntrinsicType - intrinsicName", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const stringType = project.checker.getStringType(); assert.equal((stringType as IntrinsicType).intrinsicName, "string"); @@ -7383,7 +7396,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const symbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("empty:")); assert.ok(symbol); @@ -7401,7 +7414,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("greeting:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7420,7 +7433,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const posSymbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("pos =")); @@ -7449,7 +7462,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const posSymbol = project.checker.getSymbolAtPosition("/src/main.ts", src.indexOf("pos =")); @@ -7478,7 +7491,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("greeting:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7506,7 +7519,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("greeting:"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7533,7 +7546,7 @@ describe("FreshableType - getFreshType and getRegularType", { concurrency }, () "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("Pending"); const symbol = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7565,12 +7578,12 @@ describe("Checker - isContextSensitive", { concurrency }, () => { "/src/main.ts": `export const fn = (x) => x;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); // Find the arrow function node - let arrowFn: import("@typescript/typescript/unstable/ast").Node | undefined; + let arrowFn: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (node.kind === SyntaxKind.ArrowFunction) { arrowFn = node; @@ -7590,7 +7603,7 @@ describe("Checker - isTypeAssignableTo", { concurrency }, () => { "/src/main.ts": `export {};`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const stringType = project.checker.getStringType(); const anyType = project.checker.getAnyType(); @@ -7606,7 +7619,7 @@ describe("Checker - isTypeAssignableTo", { concurrency }, () => { "/src/main.ts": `export {};`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const stringType = project.checker.getStringType(); const numberType = project.checker.getNumberType(); @@ -7621,7 +7634,7 @@ describe("Checker - isTypeAssignableTo", { concurrency }, () => { "/src/main.ts": src, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const pos = src.indexOf("x:"); const sym = project.checker.getSymbolAtPosition("/src/main.ts", pos); @@ -7658,7 +7671,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printFile", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sourceFile = snapshot.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/main.ts"); assert(sourceFile); const text = api.printer.printFile(sourceFile); @@ -7684,7 +7697,7 @@ export const obj = { m: 1, s: "hi", b: true }; "/src/data.json": `{"x": 1}`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const sourceFile = snapshot.getConfiguredProject("/tsconfig.json")!.program.getSourceFile("/src/data.json"); assert(sourceFile); assert.strictEqual(api.printer.printFile(sourceFile), `{ "x": 1 }\n`); @@ -7693,7 +7706,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created union type", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createUnionTypeNode([ createKeywordTypeNode(SyntaxKind.StringKeyword), @@ -7706,7 +7719,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created function type", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const param = createParameterDeclaration( undefined, @@ -7728,7 +7741,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created type reference", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createTypeReferenceNode(createIdentifier("Array"), [ createKeywordTypeNode(SyntaxKind.StringKeyword), @@ -7740,7 +7753,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("printNode with factory-created array type", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.NumberKeyword)); const text = api.printer.printNode(node); @@ -7750,7 +7763,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("typeToTypeNode + printNode round-trip", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const src = emitterFiles["/src/main.ts"]; @@ -7769,7 +7782,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("visitEachChild on typeToTypeNode result with keyword types", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const src = emitterFiles["/src/main.ts"]; const objPos = src.indexOf("obj"); @@ -7817,7 +7830,7 @@ export const obj = { m: 1, s: "hi", b: true }; test("typeToString", () => { using api = spawnAPI(emitterFiles); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const src = emitterFiles["/src/main.ts"]; @@ -7836,7 +7849,7 @@ export const obj = { m: 1, s: "hi", b: true }; "/src/main.ts": `export function greet(name: string): string[] { return [name]; }`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const { checker } = snapshot.getConfiguredProject("/tsconfig.json")!; const greetPos = "export function greet".indexOf("greet"); const symbol = checker.getSymbolAtPosition("/src/main.ts", greetPos); @@ -7853,13 +7866,13 @@ export const obj = { m: 1, s: "hi", b: true }; "/src/main.ts": `const foo = /asdfasf;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/main.ts"); assert.ok(sourceFile); // Find the regex literal node - let regexNode: import("@typescript/typescript/unstable/ast").Node | undefined; + let regexNode: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (node.kind === SyntaxKind.RegularExpressionLiteral) { regexNode = node; @@ -7898,7 +7911,7 @@ describe("Program - selected file emit", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...files }); using api = disposableAPI; - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.getJavaScriptEmit(["/src/a.ts", "/src/b.ts"]); assert.equal(result.emitSkipped, false); @@ -7918,7 +7931,7 @@ describe("Program - selected file emit", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...files }); using api = disposableAPI; - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.getDeclarationEmit(["/src/a.ts", "/src/b.ts"]); assert.equal(result.emitSkipped, false); @@ -7935,14 +7948,14 @@ describe("Program - selected file emit", { concurrency }, () => { test("selected file emit accepts empty arrays", () => { using api = spawnAPI({ ...files }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; assert.deepEqual((project.program.getJavaScriptEmit([])).outputFiles, new Map()); assert.deepEqual((project.program.getDeclarationEmit([])).outputFiles, new Map()); }); }); -describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => { +describe("LanguageService - formatNodeForInsertion", { concurrency }, () => { test("formats a synthesized statement with correct indentation for insertion inside a function body", () => { const files = { "/tsconfig.json": "{}", @@ -7950,7 +7963,8 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => }; using api = spawnAPI(files); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const languageService = snapshot.getConfiguredProject("/tsconfig.json")!.languageService; const node = createVariableStatement( undefined, @@ -7963,7 +7977,7 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => const sourceText = files["/src/index.ts"]; const insertionPos = sourceText.indexOf("\n console.log") + 1; - const formatted = snapshot.internal.formatNodeForInsertion(node, "/src/index.ts", insertionPos); + const formatted = languageService.formatNodeForInsertion(node, "/src/index.ts", insertionPos); assert.ok(formatted.includes("const x = 1;"), `Expected 'const x = 1;' in formatted output, got: ${JSON.stringify(formatted)}`); assert.ok(formatted.startsWith(" "), `Expected 4 spaces of indentation, got: ${JSON.stringify(formatted)}`); }); @@ -7975,7 +7989,8 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => }; using api = spawnAPI(files); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const languageService = snapshot.getConfiguredProject("/tsconfig.json")!.languageService; const node = createVariableStatement( undefined, @@ -7985,7 +8000,7 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => ), ); - const formatted = snapshot.internal.formatNodeForInsertion(node, "/src/index.ts", 0); + const formatted = languageService.formatNodeForInsertion(node, "/src/index.ts", 0); assert.ok(formatted.includes("const y = 42;"), `Expected 'const y = 42;' in formatted output, got: ${JSON.stringify(formatted)}`); assert.ok(!formatted.startsWith(" "), `Expected no leading spaces at top level, got: ${JSON.stringify(formatted)}`); }); @@ -7999,7 +8014,8 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => }; using api = spawnAPI(files); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); + const languageService = snapshot.getConfiguredProject("/tsconfig.json")!.languageService; const node = createVariableStatement( undefined, @@ -8013,7 +8029,7 @@ describe("SnapshotInternalAPI - formatNodeForInsertion", { concurrency }, () => const sourceText = files["/src/index.ts"]; const insertionPos = sourceText.indexOf("\n console.log") + 1; - const formatted = snapshot.internal.formatNodeForInsertion(node, "/src/index.ts", insertionPos); + const formatted = languageService.formatNodeForInsertion(node, "/src/index.ts", insertionPos); // The node should be indented to match the function body (4 spaces) assert.ok(formatted.includes("const x = 1;"), `Expected 'const x = 1;' in formatted output, got: ${JSON.stringify(formatted)}`); assert.ok(formatted.startsWith(" "), `Expected 4 spaces of indentation (UTF-16 offset correctly converted), got: ${JSON.stringify(formatted)}`); @@ -8027,12 +8043,12 @@ describe("modifierFlags", { concurrency }, () => { "/src/index.ts": `export async function foo() {}`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let fnNode: import("@typescript/typescript/unstable/ast").FunctionDeclaration | undefined; + let fnNode: import("@typescript/typescript/ast").FunctionDeclaration | undefined; sourceFile.forEachChild(function visit(node) { if (isFunctionDeclaration(node)) { fnNode = node; @@ -8051,12 +8067,12 @@ describe("modifierFlags", { concurrency }, () => { "/src/index.ts": `function bar() {}`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let fnNode: import("@typescript/typescript/unstable/ast").FunctionDeclaration | undefined; + let fnNode: import("@typescript/typescript/ast").FunctionDeclaration | undefined; sourceFile.forEachChild(function visit(node) { if (isFunctionDeclaration(node)) { fnNode = node; @@ -8075,13 +8091,13 @@ describe("Checker - getResolvedSymbol", { concurrency }, () => { "/src/index.ts": `const x = 1;\nconst y = x;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); // Find the 'x' identifier in `const y = x` - let refNode: import("@typescript/typescript/unstable/ast").Identifier | undefined; + let refNode: import("@typescript/typescript/ast").Identifier | undefined; sourceFile.forEachChild(function visit(node) { if (isIdentifier(node) && node.text === "x") { // We want the reference, not the declaration - take the last one @@ -8104,12 +8120,12 @@ describe("VariableDeclarationList - BlockScoped flags", { concurrency }, () => { "/src/index.ts": `let x = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let declList: import("@typescript/typescript/unstable/ast").Node | undefined; + let declList: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (isVariableDeclarationList(node)) { declList = node; @@ -8126,12 +8142,12 @@ describe("VariableDeclarationList - BlockScoped flags", { concurrency }, () => { "/src/index.ts": `const x = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); - let declList: import("@typescript/typescript/unstable/ast").Node | undefined; + let declList: import("@typescript/typescript/ast").Node | undefined; sourceFile.forEachChild(function visit(node) { if (isVariableDeclarationList(node)) { declList = node; @@ -8150,13 +8166,13 @@ describe("AST roundtrips", { concurrency }, () => { "/src/index.ts": `function test(arg: readonly number[]) { }\n`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert(sourceFile); - const param = (sourceFile.statements[0] as import("@typescript/typescript/unstable/ast").FunctionDeclaration).parameters[0]; + const param = (sourceFile.statements[0] as import("@typescript/typescript/ast").FunctionDeclaration).parameters[0]; assert(param); - const type = param.type as import("@typescript/typescript/unstable/ast").TypeOperatorNode; + const type = param.type as import("@typescript/typescript/ast").TypeOperatorNode; assert(type); assert.equal(type.kind, SyntaxKind.TypeOperator); assert.equal(type.operator, SyntaxKind.ReadonlyKeyword); @@ -8170,13 +8186,13 @@ describe("AST roundtrips", { concurrency }, () => { "/src/index.ts": `var thing = { ...other };\n`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert(sourceFile); - const stmt = sourceFile.statements[0] as import("@typescript/typescript/unstable/ast").VariableStatement; - const object = stmt.declarationList.declarations[0].initializer as import("@typescript/typescript/unstable/ast").ObjectLiteralExpression; - const assignment = object.properties[0] as import("@typescript/typescript/unstable/ast").SpreadAssignment; + const stmt = sourceFile.statements[0] as import("@typescript/typescript/ast").VariableStatement; + const object = stmt.declarationList.declarations[0].initializer as import("@typescript/typescript/ast").ObjectLiteralExpression; + const assignment = object.properties[0] as import("@typescript/typescript/ast").SpreadAssignment; assert(assignment); assert.equal(assignment.kind, SyntaxKind.SpreadAssignment); const expr = assignment.expression; @@ -8192,18 +8208,18 @@ describe("AST roundtrips", { concurrency }, () => { "/src/index.ts": `const thing = 123;\n`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert(sourceFile); { - const stmt = sourceFile.statements[0] as import("@typescript/typescript/unstable/ast").VariableStatement; + const stmt = sourceFile.statements[0] as import("@typescript/typescript/ast").VariableStatement; const list = stmt.declarationList; assert(list.flags & NodeFlags.Const); } const cloned = getSynthesizedDeepClone(sourceFile); { - const stmt = cloned.statements[0] as import("@typescript/typescript/unstable/ast").VariableStatement; + const stmt = cloned.statements[0] as import("@typescript/typescript/ast").VariableStatement; const list = stmt.declarationList; assert(list.flags & NodeFlags.Const); } @@ -8222,7 +8238,7 @@ doThing(); `, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert(sourceFile); @@ -8233,7 +8249,7 @@ doThing(); test("Factory ModifierList auto-conversion", () => { using api = spawnAPI(); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const node = createTypeAliasDeclaration( [createToken(SyntaxKind.ExportKeyword)], @@ -8261,10 +8277,10 @@ doThing(); const errors = { ...target }; for (const tsconfig of globSync("**/tsconfig.json", { cwd: tsSource })) { - const snapshot = api.createSnapshot({ openProject: resolve(tsSource, tsconfig) }); + const snapshot = api.createSnapshot({ openProjects: [resolve(tsSource, tsconfig)] }); const project = snapshot.getConfiguredProject(tsconfig); assert(project); - for (const file of project.rootFiles) { + for (const file of project.parsedCommandLine.fileNames) { const source = project.program.getSourceFile(file); assert(source); let clone: typeof source; @@ -8307,7 +8323,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getSyntacticDiagnostics("/src/index.ts"); assert.deepEqual(diags[0].startPosition, { line: 0, character: 9 }); @@ -8329,7 +8345,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getSemanticDiagnostics("/src/index.ts"); const declRange = rangeOf(source, "callback", 0); @@ -8371,7 +8387,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getSuggestionDiagnostics("/src/index.ts"); assert.deepEqual(withoutFormattingContext(diags), [{ @@ -8391,7 +8407,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getConfigFileParsingDiagnostics(); assert.deepEqual(withoutFormattingContext(diags), [{ @@ -8412,7 +8428,7 @@ describe("Program - diagnostics", { concurrency }, () => { }); using api = disposableAPI; - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const names = project.program.getConfigFileNames(); assert.deepEqual(names, ["/tsconfig.json", "/tsconfig.base.json"]); @@ -8442,7 +8458,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x: number = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getDeclarationDiagnostics("/src/index.ts"); assert.deepEqual(diags, []); @@ -8455,7 +8471,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": source, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getBindDiagnostics("/src/index.ts"); assert.deepEqual(withoutFormattingContext(diags), [ @@ -8483,7 +8499,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getProgramDiagnostics(); assert.deepEqual(withoutFormattingContext(diags), [ @@ -8510,7 +8526,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getGlobalDiagnostics(); assert.deepEqual(diags, []); @@ -8522,7 +8538,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/index.ts": `export const x = [1, 2, 3];`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getGlobalDiagnostics(); // With noLib, the checker reports "Cannot find global type" diagnostics that @@ -8549,7 +8565,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/clean.ts": `const c = 3;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getSyntacticDiagnostics(["/src/a.ts", "/src/b.ts"]); assert.deepEqual(withoutFormattingContext(diags), [ @@ -8579,7 +8595,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": sourceB, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getSemanticDiagnostics(["/src/a.ts", "/src/b.ts"]); assert.equal(diags.length, 2); @@ -8598,7 +8614,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": sourceB, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getBindDiagnostics(["/src/a.ts", "/src/b.ts"]); assert.equal(diags.length, 4); @@ -8613,7 +8629,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": `const b: = 2;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getSyntacticDiagnostics(); assert.equal(diags.length, 2); @@ -8626,7 +8642,7 @@ describe("Program - diagnostics", { concurrency }, () => { "/src/b.ts": `const b: = 2;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const diags = project.program.getSyntacticDiagnostics([]); assert.deepEqual(diags, []); @@ -8683,7 +8699,7 @@ describe("getDefaultProjectForFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const foo: string;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // The d.ts is not imported, so it is not in the project's program @@ -8799,7 +8815,7 @@ describe("getDefaultProjectForFile", { concurrency }, () => { "/node_modules/my-lib/index.d.ts": `export declare const foo: string;`, }); - api.createSnapshot({ openProject: "/tsconfig.json" }); + api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const opened = api.createSnapshot({ openFiles: ["/node_modules/my-lib/index.d.ts"] }); assert.ok( opened.getDefaultProjectForFile("/node_modules/my-lib/index.d.ts"), @@ -8835,7 +8851,7 @@ describe("Program - emit", { concurrency }, () => { fs: fs, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.emit(); assert.deepEqual(result, { @@ -8868,7 +8884,7 @@ describe("Program - emit", { concurrency }, () => { fs: fs, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.emit(EmitOnly.OnlyDts); assert.deepEqual(result, { @@ -8899,7 +8915,7 @@ describe("Program - emit", { concurrency }, () => { fs: fs, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.emit(EmitOnly.OnlyJs); assert.deepEqual(result, { @@ -8926,7 +8942,7 @@ describe("Program - emit", { concurrency }, () => { const { api: disposableAPI, fs } = spawnAPIWithFS({ ...files }); using api = disposableAPI; - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.emitToString(EmitOnly.OnlyDts); assert.deepEqual([...result.outputFiles.keys()], [ @@ -8950,7 +8966,7 @@ describe("Program - emit", { concurrency }, () => { }); using api = disposableAPI; - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.emit(); @@ -8992,7 +9008,7 @@ describe("Program - emit", { concurrency }, () => { }); using api = disposableAPI; - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const result = project.program.emit(); assert.equal(result.emitSkipped, true); @@ -9014,7 +9030,7 @@ describe("Program - emit", { concurrency }, () => { }); using api = disposableAPI; - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; assert.deepEqual(project.program.emit(), { diagnostics: [], @@ -9033,7 +9049,7 @@ describe("Program - emit", { concurrency }, () => { test("emit rejects unknown files and invalid emitOnly values", () => { using api = spawnAPI({ ...files }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; let error: unknown; @@ -9071,7 +9087,7 @@ describe("Timing", { concurrency }, () => { assert.equal(info.recentRequests.length, 0); // Exercise a JSON request and a binary source-file request. - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -9130,7 +9146,7 @@ describe("Timing", { concurrency }, () => { collectTiming: true, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sourceFile = project.program.getSourceFile("/src/index.ts"); assert.ok(sourceFile); @@ -9199,7 +9215,7 @@ describe("runWithTemporaryFileUpdate", { concurrency }, () => { "/src/index.ts": `export const x: number = 1;`, }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; // The original content type-checks cleanly. @@ -9224,7 +9240,7 @@ describe("runWithTemporaryFileUpdate", { concurrency }, () => { assert.equal(afterDiags.length, 0); // A subsequent independent snapshot can request the project again. - const snapshot2 = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot2 = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project2 = snapshot2.getConfiguredProject("/tsconfig.json")!; const diags2 = project2.program.getSemanticDiagnostics("/src/index.ts"); assert.equal(diags2.length, 0); diff --git a/packages/typescript/test/sync/api.testUtils.ts b/packages/typescript/test/sync/api.testUtils.ts index 1b10f0760cab6..c9d282d4a261e 100644 --- a/packages/typescript/test/sync/api.testUtils.ts +++ b/packages/typescript/test/sync/api.testUtils.ts @@ -1,7 +1,7 @@ import { API, type APIOptions, -} from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/sync"; import { fileURLToPath } from "node:url"; import { createVirtualFileSystem } from "../testUtils.ts"; diff --git a/packages/typescript/test/sync/ast.bench.ts b/packages/typescript/test/sync/ast.bench.ts index 30d57385d40ba..5ea08b311cf16 100644 --- a/packages/typescript/test/sync/ast.bench.ts +++ b/packages/typescript/test/sync/ast.bench.ts @@ -9,18 +9,18 @@ import type { Block, Identifier, Node, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { isBlock, isIdentifier, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { createBlock, createExpressionStatement, createIdentifier, createIfStatement, -} from "@typescript/typescript/unstable/ast/factory"; -import { API } from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/ast/factory"; +import { API } from "@typescript/typescript/sync"; import assert from "node:assert/strict"; import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; @@ -143,7 +143,7 @@ export function runBenchmarks(options?: { filter?: string; singleIteration?: boo }), }); - const snapshot = api.createSnapshot({ openProject: configPath }); + const snapshot = api.createSnapshot({ openProjects: [configPath] }); const remoteSourceFile = snapshot.getConfiguredProject(configPath)!.program.getSourceFile(sourcePath)!; assert.ok(remoteSourceFile.statements); const remoteTree = remoteSourceFile.statements[0]; diff --git a/packages/typescript/test/sync/ast.test.ts b/packages/typescript/test/sync/ast.test.ts index a9e4c665cbe48..57b5f086efd38 100644 --- a/packages/typescript/test/sync/ast.test.ts +++ b/packages/typescript/test/sync/ast.test.ts @@ -21,7 +21,7 @@ import type { StringLiteralLikeNode, TypeElement, VariableStatement, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { getCombinedModifierFlags, getNameOfDeclaration, @@ -37,11 +37,11 @@ import { NodeFlags, SyntaxKind, TokenFlags, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import { getSynthesizedDeepClone, getSynthesizedDeepClones, -} from "@typescript/typescript/unstable/ast/clone"; +} from "@typescript/typescript/ast/clone"; import { cloneNode, createBinaryExpression, @@ -56,18 +56,18 @@ import { createSourceFile, createStringLiteral, createToken, - NodeObject, -} from "@typescript/typescript/unstable/ast/factory"; +} from "@typescript/typescript/ast/factory"; import { visitEachChild, visitNode, visitNodes, -} from "@typescript/typescript/unstable/ast/visitor"; +} from "@typescript/typescript/ast/visitor"; import { API, Checker, + isRemoteNode, TypeFlags, -} from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/sync"; import assert from "node:assert"; import { describe, @@ -617,7 +617,7 @@ function spawnAPI(files: Record = { } function getRemoteSourceFileAndChecker(api: API, configPath: string, filePath: string) { - const snapshot = api.createSnapshot({ openProject: configPath }); + const snapshot = api.createSnapshot({ openProjects: [configPath] }); const project = snapshot.getConfiguredProject(configPath)!; return [project.program.getSourceFile(filePath)!, project.checker] as const; } @@ -791,13 +791,14 @@ interface I extends Parent {} } }); - test("cloneNode produces a NodeObject from a RemoteNode", () => { + test("cloneNode produces a synthesized node from a remote node", () => { const api = spawnAPI(); try { const sf = getRemoteSourceFile(api, "/tsconfig.json", "/src/foo.ts"); const clone = cloneNode(sf); assert.notStrictEqual(clone, sf); - assert.ok(clone instanceof NodeObject); + assert.ok(isRemoteNode(sf)); + assert.ok(!isRemoteNode(clone)); assert.strictEqual(clone.statements, sf.statements); assert.strictEqual(clone.text, sf.text); assert.strictEqual(clone.fileName, sf.fileName); @@ -877,7 +878,7 @@ describe("RemoteNode + visitEachChild", { concurrency }, () => { } }); - test("visitor can transform remote tree into NodeObject tree", () => { + test("visitor can transform a remote tree into a synthesized tree", () => { const api = spawnAPI(); try { const sf = getRemoteSourceFile(api, "/tsconfig.json", "/src/index.ts"); @@ -956,7 +957,7 @@ describe("RemoteNode + getSynthesizedDeepClone", { concurrency }, () => { } }); - test("deep clone of remote tree produces independent NodeObject tree", () => { + test("deep clone of remote tree produces an independent synthesized tree", () => { const api = spawnAPI(); try { const sf = getRemoteSourceFile(api, "/tsconfig.json", "/src/foo.ts"); @@ -970,7 +971,7 @@ describe("RemoteNode + getSynthesizedDeepClone", { concurrency }, () => { // But be entirely separate objects clone.forEachChild(function visit(node) { - assert.ok(node instanceof NodeObject); + assert.ok(!isRemoteNode(node)); node.forEachChild(visit); }); } diff --git a/packages/typescript/test/sync/astnav.test.ts b/packages/typescript/test/sync/astnav.test.ts index 6901c17db331f..54fb26f500709 100644 --- a/packages/typescript/test/sync/astnav.test.ts +++ b/packages/typescript/test/sync/astnav.test.ts @@ -12,12 +12,12 @@ import { formatSyntaxKind, getTokenAtPosition, getTouchingPropertyName, -} from "@typescript/typescript/unstable/ast"; +} from "@typescript/typescript/ast"; import type { Node, SourceFile, -} from "@typescript/typescript/unstable/ast"; -import { API } from "@typescript/typescript/unstable/sync"; +} from "@typescript/typescript/ast"; +import { API } from "@typescript/typescript/sync"; import assert from "node:assert"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; @@ -111,7 +111,7 @@ describe("astnav", { concurrency: areTestsFiltered() }, () => { }), }); - const snapshot = api.createSnapshot({ openProject: "/tsconfig.json" }); + const snapshot = api.createSnapshot({ openProjects: ["/tsconfig.json"] }); const project = snapshot.getConfiguredProject("/tsconfig.json")!; const sf = project.program.getSourceFile("/src/testFile.ts"); assert.ok(sf, "Failed to get source file from API"); diff --git a/packages/typescript/test/sync/shutdown.test.ts b/packages/typescript/test/sync/shutdown.test.ts index cba2c9d9fa420..83c7bfa896404 100644 --- a/packages/typescript/test/sync/shutdown.test.ts +++ b/packages/typescript/test/sync/shutdown.test.ts @@ -4,7 +4,7 @@ import { test } from "node:test"; test("close shuts down the API process cleanly", async () => { const script = ` - import { API } from "@typescript/typescript/unstable/sync"; + import { API } from "@typescript/typescript/sync"; const api = new API({ cwd: process.cwd() }); api.parseCommandLine([]); api.close(); diff --git a/packages/typescript/tsconfig.dist.json b/packages/typescript/tsconfig.dist.json new file mode 100644 index 0000000000000..0b0a3de87eec1 --- /dev/null +++ b/packages/typescript/tsconfig.dist.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "composite": false, + "module": "node16", + "noEmit": true, + "skipLibCheck": false + }, + "include": ["dist"] +} diff --git a/packages/typescript/tsconfig.json b/packages/typescript/tsconfig.json index ea7eee906ff54..3f993c6454f23 100644 --- a/packages/typescript/tsconfig.json +++ b/packages/typescript/tsconfig.json @@ -6,6 +6,7 @@ "sourceMap": true, "declaration": true, "declarationMap": true, + "stripInternal": true, "rootDir": "src", "outDir": "dist" }, diff --git a/packages/vscode-typescript/src/contentMapperContributions.ts b/packages/vscode-typescript/src/contentMapperContributions.ts index c8529d11ee8b2..607d142b12eb0 100644 --- a/packages/vscode-typescript/src/contentMapperContributions.ts +++ b/packages/vscode-typescript/src/contentMapperContributions.ts @@ -1,5 +1,5 @@ -import type { ContentMapperContribution } from "@typescript/typescript/unstable/vscode"; -export type { ContentMapperContribution, ContentMapperManifest } from "@typescript/typescript/unstable/vscode"; +import type { ContentMapperContribution } from "@typescript/typescript/vscode"; +export type { ContentMapperContribution, ContentMapperManifest } from "@typescript/typescript/vscode"; export interface SerializedContentMapperContribution { readonly contributorId: string; diff --git a/packages/vscode-typescript/src/extension.ts b/packages/vscode-typescript/src/extension.ts index 63d2b9a091625..7edd489ec2bfc 100644 --- a/packages/vscode-typescript/src/extension.ts +++ b/packages/vscode-typescript/src/extension.ts @@ -1,6 +1,6 @@ -import type { ExtensionAPI } from "@typescript/typescript/unstable/vscode"; +import type { ExtensionAPI } from "@typescript/typescript/vscode"; import * as vscode from "vscode"; -export type { ExtensionAPI } from "@typescript/typescript/unstable/vscode"; +export type { ExtensionAPI } from "@typescript/typescript/vscode"; import { registerEnablementCommands, diff --git a/packages/vscode-typescript/src/lspMiddleware.ts b/packages/vscode-typescript/src/lspMiddleware.ts index 999b38534f4fa..ad9f57f79a8b7 100644 --- a/packages/vscode-typescript/src/lspMiddleware.ts +++ b/packages/vscode-typescript/src/lspMiddleware.ts @@ -3,7 +3,7 @@ import type { LspMiddlewareMethod, LspMiddlewareResult, LspMiddlewareTransformer, -} from "@typescript/typescript/unstable/vscode"; +} from "@typescript/typescript/vscode"; import type { CancellationToken, Disposable, diff --git a/packages/vscode-typescript/src/session.ts b/packages/vscode-typescript/src/session.ts index 7bb9ae2b4c35b..943f2af6817f3 100644 --- a/packages/vscode-typescript/src/session.ts +++ b/packages/vscode-typescript/src/session.ts @@ -2,7 +2,7 @@ import type { LspMiddlewareMethod, LspMiddlewareTransformer, TypeScriptSDK, -} from "@typescript/typescript/unstable/vscode"; +} from "@typescript/typescript/vscode"; import * as path from "path"; import * as vscode from "vscode"; import { ActiveJsTsEditorTracker } from "./activeJsTsEditorTracker"; diff --git a/packages/vscode-typescript/src/tsdkPackage.ts b/packages/vscode-typescript/src/tsdkPackage.ts index 000d34429de29..b68e34379af70 100644 --- a/packages/vscode-typescript/src/tsdkPackage.ts +++ b/packages/vscode-typescript/src/tsdkPackage.ts @@ -2,7 +2,7 @@ import { type APIModules, createTypeScriptModuleLoader, type TypeScriptSDK, -} from "@typescript/typescript/unstable/vscode"; +} from "@typescript/typescript/vscode"; import fs from "node:fs"; import module from "node:module"; import path from "node:path"; diff --git a/packages/vscode-typescript/test/lspMiddleware.test.ts b/packages/vscode-typescript/test/lspMiddleware.test.ts index 40d7ccc4e685d..d1171d2a761bb 100644 --- a/packages/vscode-typescript/test/lspMiddleware.test.ts +++ b/packages/vscode-typescript/test/lspMiddleware.test.ts @@ -1,4 +1,4 @@ -import type { ExtensionAPI } from "@typescript/typescript/unstable/vscode"; +import type { ExtensionAPI } from "@typescript/typescript/vscode"; import assert from "node:assert/strict"; import { PassThrough } from "node:stream"; import test, { describe } from "node:test"; diff --git a/packages/vscode-typescript/test/tsdkPackage.test.ts b/packages/vscode-typescript/test/tsdkPackage.test.ts index ab8e577232181..15db3c931f953 100644 --- a/packages/vscode-typescript/test/tsdkPackage.test.ts +++ b/packages/vscode-typescript/test/tsdkPackage.test.ts @@ -1,4 +1,4 @@ -import { createTypeScriptModuleLoader } from "@typescript/typescript/unstable/vscode"; +import { createTypeScriptModuleLoader } from "@typescript/typescript/vscode"; import assert from "node:assert/strict"; import fs from "node:fs"; import os from "node:os"; @@ -213,7 +213,7 @@ describe("TypeScript API module loading", { concurrency: true }, () => { name: "typescript-selected", version, type: "module", - exports: { "./unstable/test": "./api.js", "./unstable/other": "./other.js" }, + exports: { "./test": "./api.js", "./other": "./other.js" }, }), ); writeManifest("1"); @@ -221,12 +221,12 @@ describe("TypeScript API module loading", { concurrency: true }, () => { fs.writeFileSync(path.join(root, "api.js"), 'export { version } from "./dependency.js";'); fs.writeFileSync(path.join(root, "other.js"), 'export { version } from "./dependency.js";'); const originalSDK = packageSDK(packageJsonPath, "1"); - assert.equal((await originalSDK.importModule("typescript/unstable/test") as { version: number; }).version, 1); + assert.equal((await originalSDK.importModule("typescript/test") as { version: number; }).version, 1); writeManifest("2"); fs.writeFileSync(path.join(root, "dependency.js"), "export const version = 2;"); - await assert.rejects(originalSDK.importModule("typescript/unstable/test"), TypeScriptPackageChangedError); - await assert.rejects(originalSDK.importModule("typescript/unstable/other"), TypeScriptPackageChangedError); + await assert.rejects(originalSDK.importModule("typescript/test"), TypeScriptPackageChangedError); + await assert.rejects(originalSDK.importModule("typescript/other"), TypeScriptPackageChangedError); let pipes = 0; const sdk = createTypeScriptSDK( @@ -238,7 +238,7 @@ describe("TypeScript API module loading", { concurrency: true }, () => { }, () => true, ); - await assert.rejects(sdk.importModule("typescript/unstable/test"), TypeScriptPackageChangedError); + await assert.rejects(sdk.importModule("typescript/test"), TypeScriptPackageChangedError); await assert.rejects(sdk.initializeAPIConnection(), TypeScriptPackageChangedError); assert.equal(pipes, 0); const replacement = path.join(root, "replacement"); @@ -247,7 +247,7 @@ describe("TypeScript API module loading", { concurrency: true }, () => { for (const file of ["api.js", "other.js", "dependency.js"]) { fs.copyFileSync(path.join(root, file), path.join(replacement, file)); } - assert.equal((await packageSDK(path.join(replacement, "package.json"), "2").importModule("typescript/unstable/test") as { version: number; }).version, 2); + assert.equal((await packageSDK(path.join(replacement, "package.json"), "2").importModule("typescript/test") as { version: number; }).version, 2); }); test("imports an exported module relative to the selected package", async t => { @@ -261,7 +261,7 @@ describe("TypeScript API module loading", { concurrency: true }, () => { name: "typescript-selected", type: "module", exports: { - "./unstable/test": "./dist/async.js", + "./test": "./dist/async.js", }, }), ); @@ -271,46 +271,46 @@ describe("TypeScript API module loading", { concurrency: true }, () => { assert.fail("Loading an API module must not open a pipe."); }, () => true); assert.equal(sdk.packageJsonPath, packageJsonPath); - const loaded = await sdk.importModule("typescript/unstable/test"); + const loaded = await sdk.importModule("typescript/test"); assert.equal((loaded as { selected: boolean; }).selected, true); - assert.equal(await sdk.importModule("typescript/unstable/test"), loaded); + assert.equal(await sdk.importModule("typescript/test"), loaded); const loader = createTypeScriptModuleLoader(packageJsonPath); - assert.equal(await loader.importModule("typescript/unstable/test"), loaded); - await assert.rejects(loader.importModule("unstable/test"), /Invalid TypeScript API module export path/); + assert.equal(await loader.importModule("typescript/test"), loaded); + await assert.rejects(loader.importModule("test"), /Invalid TypeScript API module export path/); }); type Equal = (() => T extends A ? 1 : 2) extends (() => T extends B ? 1 : 2) ? true : false; function checkType(_equal: T): void {} - async function checkPublicTypes(connection: TypeScriptSDK, exportPath: string, knownExportPath: "typescript/unstable/async" | "typescript/unstable/ast"): Promise { - const asyncModule = connection.importModule("typescript/unstable/async"); - checkType>>(true); - const syncModule = connection.importModule("typescript/unstable/sync"); - checkType>>(true); - const fsModule = connection.importModule("typescript/unstable/fs"); - checkType>>(true); - const pathModule = connection.importModule("typescript/unstable/path"); - checkType>>(true); - const protoModule = connection.importModule("typescript/unstable/proto"); - checkType>>(true); - const astModule = connection.importModule("typescript/unstable/ast"); - checkType>>(true); - const isModule = connection.importModule("typescript/unstable/ast/is"); - checkType>>(true); - const factoryModule = connection.importModule("typescript/unstable/ast/factory"); - checkType>>(true); - const utilsModule = connection.importModule("typescript/unstable/ast/utils"); - checkType>>(true); - const scannerModule = connection.importModule("typescript/unstable/ast/scanner"); - checkType>>(true); - const visitorModule = connection.importModule("typescript/unstable/ast/visitor"); - checkType>>(true); - const cloneModule = connection.importModule("typescript/unstable/ast/clone"); - checkType>>(true); + async function checkPublicTypes(connection: TypeScriptSDK, exportPath: string, knownExportPath: "typescript/async" | "typescript/ast"): Promise { + const asyncModule = connection.importModule("typescript/async"); + checkType>>(true); + const syncModule = connection.importModule("typescript/sync"); + checkType>>(true); + const fsModule = connection.importModule("typescript/fs"); + checkType>>(true); + const pathModule = connection.importModule("typescript/path"); + checkType>>(true); + const protoModule = connection.importModule("typescript/proto"); + checkType>>(true); + const astModule = connection.importModule("typescript/ast"); + checkType>>(true); + const isModule = connection.importModule("typescript/ast/is"); + checkType>>(true); + const factoryModule = connection.importModule("typescript/ast/factory"); + checkType>>(true); + const utilsModule = connection.importModule("typescript/ast/utils"); + checkType>>(true); + const scannerModule = connection.importModule("typescript/ast/scanner"); + checkType>>(true); + const visitorModule = connection.importModule("typescript/ast/visitor"); + checkType>>(true); + const cloneModule = connection.importModule("typescript/ast/clone"); + checkType>>(true); const knownModule = connection.importModule(knownExportPath); - checkType>>(true); - const unknownModule = connection.importModule("typescript/unstable/future"); + checkType>>(true); + const unknownModule = connection.importModule("typescript/future"); checkType>>(true); const dynamicModule = connection.importModule(exportPath); checkType>>(true); @@ -344,7 +344,7 @@ describe("TypeScript API module loading", { concurrency: true }, () => { assert.equal(sdk.packageJsonPath, undefined); assert.equal(await sdk.initializeAPIConnection("custom-pipe"), "custom-pipe"); assert.equal(calls, 1); - await assert.rejects(sdk.importModule("typescript/unstable/async"), /does not provide a matching JavaScript API package/); + await assert.rejects(sdk.importModule("typescript/async"), /does not provide a matching JavaScript API package/); }); test("SDK connection creation awaits the lifecycle scheduler's result", async () => { @@ -373,7 +373,7 @@ describe("TypeScript API module loading", { concurrency: true }, () => { const packageJsonPath = path.join(root, "package.json"); fs.writeFileSync(packageJsonPath, JSON.stringify({ name: "typescript-selected" })); - for (const exportPath of ["", "unstable/async", "typescript/", "@typescript/typescript/unstable/async", "./unstable/async", "../async", "/unstable/async", "typescript/unstable\\async", "typescript/../async"]) { + for (const exportPath of ["", "async", "typescript/", "@typescript/typescript/async", "./async", "../async", "/async", "typescript/unstable\\async", "typescript/../async"]) { await assert.rejects( packageSDK(packageJsonPath).importModule(exportPath), new Error(`Invalid TypeScript API module export path '${exportPath}'.`), @@ -387,7 +387,7 @@ describe("TypeScript API module loading", { concurrency: true }, () => { fs.writeFileSync(packageJsonPath, "{}"); await assert.rejects( - packageSDK(packageJsonPath).importModule("typescript/unstable/async"), + packageSDK(packageJsonPath).importModule("typescript/async"), new Error(`TypeScript API package manifest at '${packageJsonPath}' does not contain a package name.`), ); }); @@ -395,4 +395,4 @@ describe("TypeScript API module loading", { concurrency: true }, () => { import type { ExtensionAPI, TypeScriptSDK, -} from "@typescript/typescript/unstable/vscode"; +} from "@typescript/typescript/vscode"; diff --git a/tools/gen-proto/main_test.go b/tools/gen-proto/main_test.go index 92094bcf8dd55..6a7cdb969ce43 100644 --- a/tools/gen-proto/main_test.go +++ b/tools/gen-proto/main_test.go @@ -123,6 +123,15 @@ export interface RawCompilerOptions`, if strings.Contains(generated, "projects: readonly ProjectResponse[];") { t.Error("response array fields must remain mutable") } + projectResponse := generated[strings.Index(generated, "export interface ProjectResponse"):strings.Index(generated, "export interface GetSymbolAtPositionParams")] + for _, deprecated := range []string{ + "rootFiles:", + "compilerOptions:", + } { + if strings.Contains(projectResponse, deprecated) { + t.Errorf("generated ProjectResponse contains deprecated API field %q", deprecated) + } + } for _, name := range []string{"CompilerOptions", "PluginImport"} { if strings.Contains(generated, "export interface "+name+" {") { t.Errorf("%s must be imported, not regenerated from Go", name) diff --git a/tools/scripts/gen/cache.test.mts b/tools/scripts/gen/cache.test.mts index aeb4445078a4f..4dd87ed158687 100644 --- a/tools/scripts/gen/cache.test.mts +++ b/tools/scripts/gen/cache.test.mts @@ -21,7 +21,7 @@ test("cache commands use and track an explicit environment without changing the assert.deepEqual(JSON.parse(fs.readFileSync(path.join(directory, "output.json"), "utf8")), { file: "source.go", pkg: "example", - cwd: directory, + cwd: fs.realpathSync(directory), }); assert.equal(await cache(options), true); assert.equal(await cache({ ...options, env: { ...options.env, GOFILE: "other.go" } }), false); diff --git a/tools/scripts/gen/generatedFile.test.mts b/tools/scripts/gen/generatedFile.test.mts index ce1291442d2cd..d063b8d098b22 100644 --- a/tools/scripts/gen/generatedFile.test.mts +++ b/tools/scripts/gen/generatedFile.test.mts @@ -57,6 +57,7 @@ test("validate generates before building and selects the generation scope", asyn }, runTests: action("test:tsc"), runTestExtension: action("test:extension"), + runCheckAPIDeclarations: action("check:api-declarations"), runTestAPI: action("test:api"), runTestBenchmarks: action("test:benchmarks"), runTestTools: action("test:tools"), @@ -74,6 +75,7 @@ test("validate generates before building and selects the generation scope", asyn assert.equal(calls[0], "all" in options ? "generate" : "generate:go"); assert.ok(calls.indexOf("build") > 0); assert.ok(calls.indexOf("build") < calls.indexOf("test:tsc")); + assert.ok(calls.indexOf("check:api-declarations") > calls.indexOf("test:extension")); assert.equal(calls.includes("test:api"), "api" in options || "all" in options); assert.equal(calls.includes("test:tools"), "all" in options); assert.equal(calls.includes("test:options"), "all" in options); diff --git a/tools/scripts/tsc/generate-ts-ast.ts b/tools/scripts/tsc/generate-ts-ast.ts index 869b34b2e49a9..4414e14148881 100644 --- a/tools/scripts/tsc/generate-ts-ast.ts +++ b/tools/scripts/tsc/generate-ts-ast.ts @@ -699,6 +699,7 @@ function generateFactory(): string { // ── NodeObject class ── const sortedGetters = [...getterNames].sort(); + out.push(`/** @internal */`); out.push(`export class NodeObject {`); out.push(` readonly kind: SyntaxKind;`); out.push(` flags: NodeFlags = 0 as NodeFlags;`); diff --git a/tsc/internal/api/proto.go b/tsc/internal/api/proto.go index 55bede513df9e..8072445202b44 100644 --- a/tsc/internal/api/proto.go +++ b/tsc/internal/api/proto.go @@ -225,6 +225,7 @@ const ( // Language service methods MethodGetCompletionsAtPosition Method = "getCompletionsAtPosition" + MethodFormatNodeForInsertion Method = "formatNodeForInsertion" // Diagnostic methods MethodGetSyntacticDiagnostics Method = "getSyntacticDiagnostics" @@ -236,12 +237,11 @@ const ( MethodGetGlobalDiagnostics Method = "getGlobalDiagnostics" MethodGetConfigFileParsingDiagnostics Method = "getConfigFileParsingDiagnostics" // Printer methods - MethodPrintNode Method = "printNode" - MethodFormatNodeForInsertion Method = "formatNodeForInsertion" - MethodEmit Method = "emit" - MethodEmitToString Method = "emitToString" - MethodGetJavaScriptEmit Method = "getJavaScriptEmit" - MethodGetDeclarationEmit Method = "getDeclarationEmit" + MethodPrintNode Method = "printNode" + MethodEmit Method = "emit" + MethodEmitToString Method = "emitToString" + MethodGetJavaScriptEmit Method = "getJavaScriptEmit" + MethodGetDeclarationEmit Method = "getDeclarationEmit" // Intrinsic type getters MethodGetAnyType Method = "getAnyType" @@ -742,8 +742,8 @@ var unmarshalers = map[Method]func([]byte) (any, error){ MethodGetReferencedSymbolsForNode: unmarshallerFor[GetReferencedSymbolsForNodeParams], MethodGetSignatureUsages: unmarshallerFor[GetSignatureUsagesParams], MethodGetCompletionsAtPosition: unmarshallerFor[GetCompletionsAtPositionParams], - MethodPrintNode: unmarshallerFor[PrintNodeParams], MethodFormatNodeForInsertion: unmarshallerFor[FormatNodeForInsertionParams], + MethodPrintNode: unmarshallerFor[PrintNodeParams], MethodEmit: unmarshallerFor[EmitParams], MethodEmitToString: unmarshallerFor[EmitParams], MethodGetJavaScriptEmit: unmarshallerFor[SelectedFilesEmitParams], @@ -1035,10 +1035,6 @@ type ProjectResponse struct { CurrentDirectory tspath.RootedDirectoryPath `json:"currentDirectory"` Dirty bool `json:"dirty"` ParsedCommandLine *ConfigFileResponse `json:"parsedCommandLine" nonnil:"true"` - // Deprecated: Use parsedCommandLine.fileNames. - RootFiles []tspath.RootedFilePath `json:"rootFiles" nonnil:"true"` - // Deprecated: Use parsedCommandLine.options. - CompilerOptions *core.CompilerOptions `json:"compilerOptions" nonnil:"true"` } func NewConfigFileResponse(parsedCommandLine *tsoptions.ParsedCommandLine) *ConfigFileResponse { @@ -1084,8 +1080,6 @@ func NewProjectResponse(p *project.Project) *ProjectResponse { CurrentDirectory: p.CurrentDirectory(), Dirty: p.IsDirty(), ParsedCommandLine: NewConfigFileResponse(p.CommandLine), - RootFiles: p.CommandLine.FileNames(), - CompilerOptions: p.CommandLine.CompilerOptions(), } } @@ -1589,6 +1583,15 @@ type GetCompletionsAtPositionParams struct { IncludeSymbol bool `json:"includeSymbol,omitempty"` } +// FormatNodeForInsertionParams are the parameters for the formatNodeForInsertion method. +type FormatNodeForInsertionParams struct { + Snapshot SnapshotID `json:"snapshot"` + Project project.ID `json:"project"` + File DocumentIdentifier `json:"file"` // target file where the node will be inserted + Position uint32 `json:"position"` // UTF-16 code-unit offset of the insertion position in the target file + Data string `json:"data"` // base64-encoded binary AST data for the synthesized node +} + // CompletionEntryLabelDetailsResponse holds additional label display text for a completion entry. type CompletionEntryLabelDetailsResponse struct { Detail *string `json:"detail,omitempty"` @@ -1810,15 +1813,6 @@ type EmitOutputResponse struct { OutputFiles []*EmitOutputFile `json:"outputFiles" nonnil:"true"` } -// FormatNodeForInsertionParams are the parameters for the formatNodeForInsertion method. -type FormatNodeForInsertionParams struct { - Snapshot SnapshotID `json:"snapshot"` - Project project.ID `json:"project"` - File DocumentIdentifier `json:"file"` // target file where the node will be inserted - Position uint32 `json:"position"` // UTF-16 code-unit offset of the insertion position in the target file - Data string `json:"data"` // base64-encoded binary AST data for the synthesized node -} - // CheckerTypeParams are parameters for checker methods that operate on a type. type CheckerTypeParams struct { Snapshot SnapshotID `json:"snapshot"` diff --git a/tsc/internal/api/session.go b/tsc/internal/api/session.go index e44b35895353b..620551a98398c 100644 --- a/tsc/internal/api/session.go +++ b/tsc/internal/api/session.go @@ -1101,8 +1101,6 @@ func (s *Session) HandleRequest(ctx context.Context, method string, params json. return s.handleTypeToString(ctx, parsed.(*TypeToTypeNodeParams)) case string(MethodPrintNode): return s.handlePrintNode(ctx, parsed.(*PrintNodeParams)) - case string(MethodFormatNodeForInsertion): - return s.handleFormatNodeForInsertion(ctx, parsed.(*FormatNodeForInsertionParams)) case string(MethodEmit): return s.handleEmit(ctx, parsed.(*EmitParams)) case string(MethodEmitToString): @@ -1241,6 +1239,8 @@ func (s *Session) HandleRequest(ctx context.Context, method string, params json. return s.handleGetSignatureUsages(ctx, parsed.(*GetSignatureUsagesParams)) case string(MethodGetCompletionsAtPosition): return s.handleGetCompletionsAtPosition(ctx, parsed.(*GetCompletionsAtPositionParams)) + case string(MethodFormatNodeForInsertion): + return s.handleFormatNodeForInsertion(ctx, parsed.(*FormatNodeForInsertionParams)) default: return nil, fmt.Errorf("unknown method: %s", method) } diff --git a/tsc/internal/api/session_createprogram_test.go b/tsc/internal/api/session_createprogram_test.go index 3282afae21a9c..54709aec92d6a 100644 --- a/tsc/internal/api/session_createprogram_test.go +++ b/tsc/internal/api/session_createprogram_test.go @@ -75,9 +75,9 @@ func TestCreateSnapshotCreatesPrograms(t *testing.T) { assert.DeepEqual(t, *response.Operation.CreatedPrograms, []project.SyntheticProjectID{syntheticProjectID(1), syntheticProjectID(2)}) assert.Assert(t, response.Projects[0].ConfigFileName == nil) assert.Assert(t, response.Projects[1].ConfigFileName == nil) - assert.DeepEqual(t, response.Projects[0].RootFiles, []tspath.RootedFilePath{fileA, fileB}) - assert.Equal(t, response.Projects[0].CompilerOptions.Strict, core.TSTrue) - assert.DeepEqual(t, response.Projects[1].RootFiles, []tspath.RootedFilePath{fileB}) + assert.DeepEqual(t, response.Projects[0].ParsedCommandLine.FileNames, []tspath.RootedFilePath{fileA, fileB}) + assert.Equal(t, response.Projects[0].ParsedCommandLine.Options.Strict, core.TSTrue) + assert.DeepEqual(t, response.Projects[1].ParsedCommandLine.FileNames, []tspath.RootedFilePath{fileB}) snapshot, err := session.getSnapshotData(response.Snapshot) assert.NilError(t, err) @@ -170,8 +170,8 @@ func TestUpdateSnapshotReconfiguresSyntheticProgram(t *testing.T) { }) assert.NilError(t, err) assert.Equal(t, reconfigured.Projects[0].Id, project.ID(programID)) - assert.DeepEqual(t, reconfigured.Projects[0].RootFiles, []tspath.RootedFilePath{"/home/projects/p/b.ts"}) - assert.Equal(t, reconfigured.Projects[0].CompilerOptions.Strict, core.TSTrue) + assert.DeepEqual(t, reconfigured.Projects[0].ParsedCommandLine.FileNames, []tspath.RootedFilePath{"/home/projects/p/b.ts"}) + assert.Equal(t, reconfigured.Projects[0].ParsedCommandLine.Options.Strict, core.TSTrue) } func TestReconfigureSyntheticProgramValidation(t *testing.T) {