Skip to content

Commit 6b2c650

Browse files
committed
Merge remote-tracking branch 'upstream/main' into redo-ast-method-dispatch-opt
2 parents 569a137 + b5c34ba commit 6b2c650

393 files changed

Lines changed: 26358 additions & 5431 deletions

File tree

Some content is hidden

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

‎Herebyfile.mjs‎

Lines changed: 125 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,17 @@ export const buildAPI = task({
10341034
},
10351035
});
10361036

1037+
async function runCheckAPIDeclarations() {
1038+
await run("node", ["./node_modules/typescript/bin/tsc", "-p", "packages/typescript/tsconfig.dist.json"]);
1039+
}
1040+
1041+
export const checkAPIDeclarations = task({
1042+
name: "check:api-declarations",
1043+
description: "Type-checks the emitted @typescript/typescript declaration files.",
1044+
dependencies: [buildAPI],
1045+
run: runCheckAPIDeclarations,
1046+
});
1047+
10371048
async function runBuildAPITests(generateSources = true) {
10381049
if (generateSources) await runGenerateSync();
10391050
await run("npm", ["run", "-w", "@typescript/typescript", "build:test"]);
@@ -1221,6 +1232,7 @@ export const validate = task({
12211232

12221233
await runValidation("test:tsc", runTests);
12231234
await runValidation("test:extension", runTestExtension);
1235+
await runValidation("check:api-declarations", runCheckAPIDeclarations);
12241236
if (options.api || options.all) {
12251237
if (!options.all) await runGenerateEnums();
12261238
await runBuildAPITests(!options.all);
@@ -2343,6 +2355,7 @@ async function runBuildNativePreviewPackages() {
23432355

23442356
// Build JS API and copy dist into the package.
23452357
await run("npm", ["run", "-w", "@typescript/typescript", "build"]);
2358+
await runCheckAPIDeclarations();
23462359
await cpRecursive(path.join(inputDir, "dist"), path.join(mainPackageDir, "dist"));
23472360

23482361
// Validate that .d.ts files contain no external imports (all imports must start with "." or "#").
@@ -2673,38 +2686,42 @@ async function runPackNativePreviewPackages() {
26732686
export const packVsixExtensions = task({
26742687
name: "vscode-typescript:pack",
26752688
hiddenFromTaskList: true,
2676-
dependencies: options.forRelease || usePublishedPlatformPackagesForVsix ? undefined : [buildNativePreviewPackages, cleanSignTempDirectory],
2689+
dependencies: options.forRelease || usePublishedPlatformPackagesForVsix ? undefined : [packNativePreviewPackages],
26772690
run: runPackVsixExtensions,
26782691
});
26792692

26802693
/** @type {Map<string, Promise<string>>} */
2681-
const publishedPlatformPackageLibDirs = new Map();
2694+
const publishedPlatformPackageDirs = new Map();
26822695

2683-
const getPublishedTypeScriptPackageJson = memoize(() => {
2696+
const getPublishedTypeScriptPackageDir = memoize(() => {
26842697
const candidates = [
2685-
path.join(extensionDir, "node_modules", publishedTypeScriptAliasPackageName, "package.json"),
2686-
path.join(__dirname, "node_modules", publishedTypeScriptAliasPackageName, "package.json"),
2698+
path.join(extensionDir, "node_modules", publishedTypeScriptAliasPackageName),
2699+
path.join(__dirname, "node_modules", publishedTypeScriptAliasPackageName),
26872700
];
26882701

26892702
for (const candidate of candidates) {
2690-
if (fs.existsSync(candidate)) {
2691-
const packageJson = JSON.parse(fs.readFileSync(candidate, "utf8"));
2692-
if (packageJson.name !== "typescript") {
2693-
throw new Error(`${publishedTypeScriptAliasPackageName} should alias the typescript package, but found ${packageJson.name}.`);
2694-
}
2695-
if (!packageJson.version || typeof packageJson.version !== "string") {
2696-
throw new Error(`${publishedTypeScriptAliasPackageName} package.json did not contain a version.`);
2697-
}
2698-
if (!packageJson.optionalDependencies || typeof packageJson.optionalDependencies !== "object") {
2699-
throw new Error(`${publishedTypeScriptAliasPackageName} package.json did not contain platform optionalDependencies.`);
2700-
}
2701-
return packageJson;
2703+
if (fs.existsSync(path.join(candidate, "package.json"))) {
2704+
return candidate;
27022705
}
27032706
}
27042707

27052708
throw new Error(`Could not find ${publishedTypeScriptAliasPackageName}; run npm install first.`);
27062709
});
27072710

2711+
const getPublishedTypeScriptPackageJson = memoize(() => {
2712+
const packageJson = JSON.parse(fs.readFileSync(path.join(getPublishedTypeScriptPackageDir(), "package.json"), "utf8"));
2713+
if (packageJson.name !== "typescript") {
2714+
throw new Error(`${publishedTypeScriptAliasPackageName} should alias the typescript package, but found ${packageJson.name}.`);
2715+
}
2716+
if (!packageJson.version || typeof packageJson.version !== "string") {
2717+
throw new Error(`${publishedTypeScriptAliasPackageName} package.json did not contain a version.`);
2718+
}
2719+
if (!packageJson.optionalDependencies || typeof packageJson.optionalDependencies !== "object") {
2720+
throw new Error(`${publishedTypeScriptAliasPackageName} package.json did not contain platform optionalDependencies.`);
2721+
}
2722+
return packageJson;
2723+
});
2724+
27082725
function getPublishedTypeScriptVersion() {
27092726
const version = getPublishedTypeScriptPackageJson().version;
27102727
if (releaseVscodeTypescript && !stableThreeComponentVersionPattern.test(version)) {
@@ -2725,23 +2742,23 @@ const getPackageLock = memoize(() => JSON.parse(fs.readFileSync(path.join(__dirn
27252742
/**
27262743
* @param {string} npmPackageName
27272744
*/
2728-
async function getPublishedPlatformPackageLibDir(npmPackageName) {
2729-
let promise = publishedPlatformPackageLibDirs.get(npmPackageName);
2745+
async function getPublishedPlatformPackageDir(npmPackageName) {
2746+
let promise = publishedPlatformPackageDirs.get(npmPackageName);
27302747
if (!promise) {
2731-
promise = getPublishedPlatformPackageLibDirWorker(npmPackageName);
2732-
publishedPlatformPackageLibDirs.set(npmPackageName, promise);
2748+
promise = getPublishedPlatformPackageDirWorker(npmPackageName);
2749+
publishedPlatformPackageDirs.set(npmPackageName, promise);
27332750
}
27342751
return promise;
27352752
}
27362753

27372754
/**
27382755
* @param {string} npmPackageName
27392756
*/
2740-
async function getPublishedPlatformPackageLibDirWorker(npmPackageName) {
2757+
async function getPublishedPlatformPackageDirWorker(npmPackageName) {
27412758
const dest = path.join(builtPublishedPlatformPackages, "node_modules", ...npmPackageName.split("/"));
27422759
const lib = path.join(dest, "lib");
27432760
if (fs.existsSync(lib)) {
2744-
return lib;
2761+
return dest;
27452762
}
27462763

27472764
await fs.promises.mkdir(dest, { recursive: true });
@@ -2799,26 +2816,27 @@ async function getPublishedPlatformPackageLibDirWorker(npmPackageName) {
27992816
throw new Error(`Published platform package ${npmPackageName}@${version} did not contain a lib directory.`);
28002817
}
28012818

2802-
return lib;
2819+
return dest;
28032820
}
28042821

28052822
async function runPackVsixExtensions() {
28062823
await rimraf(builtVsix);
28072824
await fs.promises.mkdir(builtVsix, { recursive: true });
28082825
if (usePublishedPlatformPackagesForVsix) {
28092826
checkPublishedPlatformPackagesForVsix();
2810-
publishedPlatformPackageLibDirs.clear();
2827+
publishedPlatformPackageDirs.clear();
28112828
await rimraf(builtPublishedPlatformPackages);
28122829
}
28132830

28142831
const platforms = getPlatforms();
2815-
const extensions = platforms.flatMap(({ npmDir, npmPackageName, extensions }) => extensions.map(e => ({ npmDir, npmPackageName, ...e })));
2832+
const extensions = platforms.flatMap(({ npmTarball, npmPackageName, extensions }) => extensions.map(e => ({ npmTarball, npmPackageName, ...e })));
28162833
if (!extensions.length) {
28172834
console.log("No VSIX targets configured; skipping extension packaging.");
28182835
return;
28192836
}
28202837

28212838
// We don't use vscode:prepublish, as that would run the build for each package below.
2839+
await run("npm", ["run", "-w", "@typescript/typescript", "build"]);
28222840
await run("npm", ["run", "bundle:release"], { cwd: extensionDir, env: releasePackageEnv });
28232841

28242842
let version = "0.0.0";
@@ -2844,29 +2862,43 @@ async function runPackVsixExtensions() {
28442862

28452863
console.log("Version:", version);
28462864

2847-
await Promise.all(extensions.map(async ({ npmDir, npmPackageName, nodeOs, vscodeTarget, sourceDir, extensionDir: thisExtensionDir, vsixPath, vsixManifestPath, vsixSignaturePath }) => {
2848-
const npmLibDir = usePublishedPlatformPackagesForVsix
2849-
? await getPublishedPlatformPackageLibDir(npmPackageName)
2850-
: path.join(npmDir, "lib");
2851-
const extensionLibDir = path.join(thisExtensionDir, "lib");
2852-
await fs.promises.mkdir(extensionLibDir, { recursive: true });
2865+
await Promise.all(extensions.map(async ({ npmTarball, npmPackageName, nodeOs, vscodeTarget, sourceDir, extensionDir: thisExtensionDir, vsixPath, vsixManifestPath, vsixSignaturePath }) => {
2866+
const nodeModules = path.join(thisExtensionDir, "node_modules");
2867+
const embeddedPlatformPackageDir = path.join(nodeModules, ...npmPackageName.split("/"));
2868+
const embeddedTypeScriptDir = path.join(nodeModules, "typescript");
28532869

28542870
await cpWithoutNodeModulesOrTsconfig(sourceDir, thisExtensionDir);
2855-
await cpWithoutNodeModulesOrTsconfig(npmLibDir, extensionLibDir);
2856-
await fs.promises.chmod(path.join(extensionLibDir, nativePreviewExeName(nodeOs)), 0o755);
2871+
if (usePublishedPlatformPackagesForVsix) {
2872+
await cpRecursive(await getPublishedPlatformPackageDir(npmPackageName), embeddedPlatformPackageDir);
2873+
await cpRecursive(getPublishedTypeScriptPackageDir(), embeddedTypeScriptDir, p => !p.endsWith("/node_modules"));
2874+
}
2875+
else {
2876+
await fs.promises.mkdir(embeddedPlatformPackageDir, { recursive: true });
2877+
await fs.promises.mkdir(embeddedTypeScriptDir, { recursive: true });
2878+
await tar.x({ file: npmTarball, cwd: embeddedPlatformPackageDir, strip: 1 });
2879+
await tar.x({ file: mainNativePreviewPackage.npmTarball, cwd: embeddedTypeScriptDir, strip: 1 });
2880+
}
2881+
await fs.promises.chmod(path.join(embeddedPlatformPackageDir, "lib", nativePreviewExeName(nodeOs)), 0o755);
2882+
const embeddedTypeScriptPackageJson = JSON.parse(await fs.promises.readFile(path.join(embeddedTypeScriptDir, "package.json"), "utf8"));
28572883

28582884
const packageJsonPath = path.join(thisExtensionDir, "package.json");
28592885
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
28602886
packageJson.version = version;
28612887
packageJson.bundledTypeScriptVersion = usePublishedPlatformPackagesForVsix ? getPublishedTypeScriptVersion() : getVersion();
2888+
packageJson.dependencies = {
2889+
typescript: embeddedTypeScriptPackageJson.name === "typescript"
2890+
? embeddedTypeScriptPackageJson.version
2891+
: `npm:${embeddedTypeScriptPackageJson.name}@${embeddedTypeScriptPackageJson.version}`,
2892+
};
28622893
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, undefined, 4));
28632894

28642895
await fs.promises.copyFile("NOTICE.txt", path.join(thisExtensionDir, "NOTICE.txt"));
28652896

2866-
await run("vsce", ["package", version, "--no-update-package-json", "--no-dependencies", "--out", vsixPath, "--target", vscodeTarget], {
2897+
await run("vsce", ["package", version, "--no-update-package-json", "--no-yarn", "--out", vsixPath, "--target", vscodeTarget], {
28672898
cwd: thisExtensionDir,
28682899
env: releasePackageEnv,
28692900
});
2901+
await testVsixPackage(vsixPath, thisExtensionDir, npmPackageName, nodeOs, vscodeTarget);
28702902

28712903
if (options.forRelease) {
28722904
await run("vsce", ["generate-manifest", "--packagePath", vsixPath, "--out", vsixManifestPath], {
@@ -2878,6 +2910,64 @@ async function runPackVsixExtensions() {
28782910
}));
28792911
}
28802912

2913+
/**
2914+
* @param {string} vsixPath
2915+
* @param {string} extensionPath
2916+
* @param {string} platformPackageName
2917+
* @param {string} nodeOs
2918+
* @param {string} vscodeTarget
2919+
*/
2920+
async function testVsixPackage(vsixPath, extensionPath, platformPackageName, nodeOs, vscodeTarget) {
2921+
const zip = new AdmZip(vsixPath);
2922+
for (const packageName of ["typescript", platformPackageName]) {
2923+
const packagePath = path.join(extensionPath, "node_modules", ...packageName.split("/"));
2924+
const files = await fs.promises.readdir(packagePath, { recursive: true, withFileTypes: true });
2925+
for (const file of files) {
2926+
if (!file.isFile()) continue;
2927+
const filePath = path.join(file.parentPath, file.name);
2928+
const archivePath = `extension/node_modules/${packageName}/${path.relative(packagePath, filePath).replace(/\\/g, "/")}`;
2929+
const entry = zip.getEntry(archivePath);
2930+
assert(entry, `VSIX is missing ${archivePath}`);
2931+
assert.deepEqual(entry.getData(), await fs.promises.readFile(filePath), `VSIX changed ${archivePath}`);
2932+
}
2933+
}
2934+
2935+
const hostTarget = `${process.platform}-${process.arch === "arm" ? "armhf" : process.arch}`;
2936+
if (vscodeTarget !== hostTarget) return;
2937+
2938+
const directory = await fs.promises.mkdtemp(path.join(os.tmpdir(), "typescript-vsix-test-"));
2939+
try {
2940+
zip.extractAllTo(directory);
2941+
const platformPath = path.join(directory, "extension", "node_modules", ...platformPackageName.split("/"));
2942+
await fs.promises.chmod(path.join(platformPath, "lib", nativePreviewExeName(nodeOs)), 0o755);
2943+
await fs.promises.writeFile(path.join(directory, "tsconfig.json"), '{"files": []}\n');
2944+
await run(process.execPath, [
2945+
"--input-type=module",
2946+
"--eval",
2947+
`
2948+
import assert from "node:assert/strict";
2949+
import { createRequire } from "node:module";
2950+
import { pathToFileURL } from "node:url";
2951+
const require = createRequire(process.cwd() + "/extension/node_modules/typescript/package.json");
2952+
const manifest = require("./package.json");
2953+
for (const mode of ["async", "sync"]) {
2954+
const exportPath = manifest.exports?.["./" + mode] ? mode : "unstable/" + mode;
2955+
const { API } = await import(pathToFileURL(require.resolve(manifest.name + "/" + exportPath)).href);
2956+
const api = new API();
2957+
try {
2958+
assert.ok(await api.parseConfigFile(process.cwd() + "/tsconfig.json"));
2959+
} finally {
2960+
await api.close();
2961+
}
2962+
}
2963+
`,
2964+
], { cwd: directory });
2965+
}
2966+
finally {
2967+
await fs.promises.rm(directory, { recursive: true, force: true });
2968+
}
2969+
}
2970+
28812971
export const signVsixExtensions = task({
28822972
name: "vscode-typescript:sign",
28832973
hiddenFromTaskList: true,

‎packages/typescript/package.json‎

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,54 +41,55 @@
4141
"./schemas/tsconfig.schema.json": "./schemas/tsconfig.schema.json",
4242
"./schemas/jsconfig.schema.json": "./schemas/jsconfig.schema.json",
4343
".": "./lib/version.cjs",
44-
"./unstable/vscode": {
45-
"types": "./dist/vscode/extensionApi.d.ts"
44+
"./vscode": {
45+
"@typescript/source": "./src/vscode/extensionApi.ts",
46+
"default": "./dist/vscode/extensionApi.js"
4647
},
47-
"./unstable/sync": {
48+
"./sync": {
4849
"@typescript/source": "./src/api/sync/api.ts",
4950
"default": "./dist/api/sync/api.js"
5051
},
51-
"./unstable/async": {
52+
"./async": {
5253
"@typescript/source": "./src/api/async/api.ts",
5354
"default": "./dist/api/async/api.js"
5455
},
55-
"./unstable/fs": {
56+
"./fs": {
5657
"@typescript/source": "./src/api/fs.ts",
5758
"default": "./dist/api/fs.js"
5859
},
59-
"./unstable/path": {
60+
"./path": {
6061
"@typescript/source": "./src/api/typedPaths.ts",
6162
"default": "./dist/api/typedPaths.js"
6263
},
63-
"./unstable/proto": {
64+
"./proto": {
6465
"@typescript/source": "./src/api/proto.ts",
6566
"default": "./dist/api/proto.js"
6667
},
67-
"./unstable/ast": {
68+
"./ast": {
6869
"@typescript/source": "./src/ast/index.ts",
6970
"default": "./dist/ast/index.js"
7071
},
71-
"./unstable/ast/is": {
72+
"./ast/is": {
7273
"@typescript/source": "./src/ast/is.ts",
7374
"default": "./dist/ast/is.js"
7475
},
75-
"./unstable/ast/factory": {
76+
"./ast/factory": {
7677
"@typescript/source": "./src/ast/factory.generated.ts",
7778
"default": "./dist/ast/factory.generated.js"
7879
},
79-
"./unstable/ast/utils": {
80+
"./ast/utils": {
8081
"@typescript/source": "./src/ast/utils.ts",
8182
"default": "./dist/ast/utils.js"
8283
},
83-
"./unstable/ast/scanner": {
84+
"./ast/scanner": {
8485
"@typescript/source": "./src/ast/scanner.ts",
8586
"default": "./dist/ast/scanner.js"
8687
},
87-
"./unstable/ast/visitor": {
88+
"./ast/visitor": {
8889
"@typescript/source": "./src/ast/visitor.ts",
8990
"default": "./dist/ast/visitor.js"
9091
},
91-
"./unstable/ast/clone": {
92+
"./ast/clone": {
9293
"@typescript/source": "./src/ast/clone.ts",
9394
"default": "./dist/ast/clone.js"
9495
}

0 commit comments

Comments
 (0)