diff --git a/demo/package.json b/demo/package.json index b1d32a50..b8450be0 100644 --- a/demo/package.json +++ b/demo/package.json @@ -9,8 +9,8 @@ "compile": "tsc", "start": "NODE_OPTIONS=--experimental-import-meta-resolve vite --config vite.config.ts", "start:debug": "vite --config vite.config.ts --debug --force", - "build": "vite --config vite.config.ts build", - "build:github": "vite --config vite.github-page.config.ts build && touch dist/.nojekyll", + "build": "tsc --noEmit && vite --config vite.config.ts build", + "build:github": "tsc --noEmit && vite --config vite.github-page.config.ts build && touch dist/.nojekyll", "start:debugServer": "node --loader ts-node/esm src/debugServer.ts", "start:extHostServer": "vscode-ext-host-server --without-connection-token" }, diff --git a/demo/tsconfig.json b/demo/tsconfig.json index 1d7f1e98..dd632cfe 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -16,6 +16,7 @@ "noImplicitReturns": true, "baseUrl": ".", "paths": { + "vscode/vscode/*": ["../dist/main/vscode/src/*"], "vscode/*": ["../dist/main/*"] } }, diff --git a/demo/vite.config.ts b/demo/vite.config.ts index 4e97cc68..4757f314 100644 --- a/demo/vite.config.ts +++ b/demo/vite.config.ts @@ -71,8 +71,7 @@ export default defineConfig({ '@codingame/monaco-vscode-typescript-language-features-default-extension', '@codingame/monaco-vscode-markdown-language-features-default-extension', '@codingame/monaco-vscode-json-language-features-default-extension', '@codingame/monaco-vscode-css-language-features-default-extension', '@codingame/monaco-vscode-npm-default-extension', '@codingame/monaco-vscode-css-default-extension', '@codingame/monaco-vscode-markdown-basics-default-extension', '@codingame/monaco-vscode-html-default-extension', - '@codingame/monaco-vscode-html-language-features-default-extension', '@codingame/monaco-vscode-configuration-editing-default-extension', '@codingame/monaco-vscode-media-preview-default-extension', '@codingame/monaco-vscode-markdown-math-default-extension', - 'vscode/workers/textmate.worker' + '@codingame/monaco-vscode-html-language-features-default-extension', '@codingame/monaco-vscode-configuration-editing-default-extension', '@codingame/monaco-vscode-media-preview-default-extension', '@codingame/monaco-vscode-markdown-math-default-extension' ], esbuildOptions: { plugins: [{ diff --git a/package-lock.json b/package-lock.json index e1d63906..e8b64ae6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,6 +60,7 @@ "@types/yauzl": "^2.10.0", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "@typescript/vfs": "^1.5.0", "@vscode/iconv-lite-umd": "^0.7.0", "@web/rollup-plugin-import-meta-assets": "^2.1.0", "change-package-name": "^1.0.5", @@ -3064,6 +3065,15 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript/vfs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.5.0.tgz", + "integrity": "sha512-AJS307bPgbsZZ9ggCT3wwpg3VbTKMFNHfaY/uF0ahSkYYrPF2dSSKDNIDIQAHm9qJqbLvCsSJH7yN4Vs/CsMMg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1" + } + }, "node_modules/@vscode/iconv-lite-umd": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz", diff --git a/package.json b/package.json index edc9fc85..f87e3e90 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ }, "type": "module", "scripts": { - "build": "npm run clean && npm run generate-types && npm run lint && npm run compile-rollup-plugins && npm run compile-treemending-script && npm run compile && npm run compile-server && npm run compile-default-extensions && npm run copy-monaco-editor", + "build": "npm run clean && npm run lint && npm run compile && npm run compile-rollup-plugins && npm run generate-types && npm run compile-treemending-script && npm run compile-server && npm run compile-default-extensions && npm run copy-monaco-editor", "compile": "NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.config.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config.json`}' --vscode-version ${npm_package_config_vscode_version} --vscode-ref ${npm_package_config_vscode_ref}", "compile-default-extensions": "NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.default-extensions.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-default-extensions.json`}'", "clean": "rm -rf dist/", @@ -59,6 +59,7 @@ "@types/yauzl": "^2.10.0", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "@typescript/vfs": "^1.5.0", "@vscode/iconv-lite-umd": "^0.7.0", "@web/rollup-plugin-import-meta-assets": "^2.1.0", "change-package-name": "^1.0.5", diff --git a/rollup/rollup-metadata-plugin.ts b/rollup/rollup-metadata-plugin.ts index 6c1e43a7..2f6bfaa8 100644 --- a/rollup/rollup-metadata-plugin.ts +++ b/rollup/rollup-metadata-plugin.ts @@ -1,33 +1,59 @@ -import type { OutputBundle, OutputOptions, Plugin, PluginContext } from 'rollup' +import type { OutputBundle, OutputChunk, OutputOptions, Plugin, PluginContext } from 'rollup' import { builtinModules } from 'module' +import path from 'path' interface Group { name: string dependencies: Set + modules: Set entrypoints: Set } interface Options { + stage?: 'generateBundle' | 'writeBundle' getGroup?: (entryPoint: string, options: OutputOptions) => string - handle (this: PluginContext, groupName: string, dependencies: Set, entrypoints: Set, options: OutputOptions, bundle: OutputBundle): void | Promise + handle (this: PluginContext, groupName: string, dependencies: Set, entrypoints: Set, exclusiveModules: Set, options: OutputOptions, bundle: OutputBundle): void | Promise } -export default ({ handle, getGroup = () => 'main' }: Options): Plugin => ({ +export default ({ handle, getGroup = () => 'main', stage = 'generateBundle' }: Options): Plugin => ({ name: 'generate-metadata', - async generateBundle (options: OutputOptions, bundle: OutputBundle) { - const externalDependencyCache = new Map>() - const getModuleExternalDependencies = (id: string, path: string[]): Set => { - if (!externalDependencyCache.has(id)) { + [stage]: async function (this: PluginContext, options: OutputOptions, bundle: OutputBundle) { + const dependencyCache = new Map, internals: Set }>() + + const inputToOutput = Object.fromEntries(Object.values(bundle) + .filter((chunk): chunk is OutputChunk => 'code' in chunk) + .map(chunk => [ + chunk.facadeModuleId, + path.resolve(options.dir!, chunk.preliminaryFileName) + ])) + const getModuleDependencies = (id: string, path: string[]): { externals: Set, internals: Set } => { + if (path.includes(id)) { + // Break recursive imports + return { + externals: new Set(), + internals: new Set() + } + } + if (!dependencyCache.has(id)) { const moduleInfo = this.getModuleInfo(id)! if (moduleInfo.isExternal) { const match = /^(?:@[^/]*\/)?[^/]*/.exec(id) - externalDependencyCache.set(id, new Set(match != null && !builtinModules.includes(match[0]) ? [match[0]] : [])) + dependencyCache.set(id, { + externals: new Set(match != null && !builtinModules.includes(match[0]) ? [match[0]] : []), + internals: new Set([]) + }) } else { - externalDependencyCache.set(id, new Set([...moduleInfo.importedIds, ...moduleInfo.dynamicallyImportedIds].flatMap(depId => Array.from(getModuleExternalDependencies(depId, [...path, id]))))) + const dependencies = [...moduleInfo.importedIds, ...moduleInfo.dynamicallyImportedIds].map(depId => { + return getModuleDependencies(depId, [...path, id]) + }) + dependencyCache.set(id, { + externals: new Set(dependencies.map(t => t.externals).flatMap(map => Array.from(map))), + internals: new Set([inputToOutput[id] ?? id, ...dependencies.map(t => t.internals).flatMap(map => Array.from(map))]) + }) } } - return externalDependencyCache.get(id)! + return dependencyCache.get(id)! } const groups = new Map() @@ -37,22 +63,32 @@ export default ({ handle, getGroup = () => 'main' }: Options): Plugin => ({ continue } const groupName = getGroup(id, options) - const externalDependencies = getModuleExternalDependencies(moduleInfo.id, []) + const dependencies = getModuleDependencies(moduleInfo.id, []) if (!groups.has(groupName)) { groups.set(groupName, { dependencies: new Set(), entrypoints: new Set(), - name: groupName + name: groupName, + modules: new Set() }) } const group = groups.get(groupName)! - externalDependencies.forEach(d => group.dependencies.add(d)) + dependencies.externals.forEach(d => group.dependencies.add(d)) + dependencies.internals.forEach(d => group.modules.add(d)) group.entrypoints.add(id) } + const moduleUseCount = new Map() + for (const [_, group] of groups.entries()) { + for (const module of group.modules) { + moduleUseCount.set(module, (moduleUseCount.get(module) ?? 0) + 1) + } + } + await Promise.all(Array.from(groups.entries()).map(async ([name, group]) => { - await handle.call(this, name, group.dependencies, group.entrypoints, options, bundle) + const exclusiveModules = new Set(Array.from(group.modules).filter(module => moduleUseCount.get(module)! <= 1)) + await handle.call(this, name, group.dependencies, exclusiveModules, group.entrypoints, options, bundle) })) } }) diff --git a/rollup/rollup.config.ts b/rollup/rollup.config.ts index 4ed62731..2aed9bdb 100644 --- a/rollup/rollup.config.ts +++ b/rollup/rollup.config.ts @@ -111,6 +111,8 @@ const BASE_DIR = path.resolve(__dirname, '..') const TSCONFIG = path.resolve(BASE_DIR, 'tsconfig.rollup.json') const SRC_DIR = path.resolve(BASE_DIR, 'src') const DIST_DIR = path.resolve(BASE_DIR, 'dist') +const DIST_DIR_MAIN = path.resolve(DIST_DIR, 'main') +const VSCODE_SRC_DIST_DIR = path.resolve(DIST_DIR_MAIN, 'vscode', 'src') const VSCODE_DIR = path.resolve(BASE_DIR, 'vscode') const VSCODE_SRC_DIR = path.resolve(VSCODE_DIR, 'src') const NODE_MODULES_DIR = path.resolve(BASE_DIR, 'node_modules') @@ -755,7 +757,11 @@ export default (args: Record): rollup.RollupOptions[] => { chunkFileNames: '[name].js', hoistTransitiveImports: false }], - plugins: [{ + plugins: [importMetaAssets({ + include: ['**/*.ts', '**/*.js'], + // assets are externals and this plugin is not able to ignore external assets + exclude: ['**/service-override/textmate.js', '**/service-override/languageDetectionWorker.js'] + }), { name: 'improve-treeshaking', transform (code) { const ast = recast.parse(code, { @@ -836,7 +842,7 @@ export default (args: Record): rollup.RollupOptions[] => { } return 'main' }, - async handle (groupName, dependencies, entrypoints, options) { + async handle (groupName, dependencies, exclusiveModules, entrypoints, options, bundle) { if (groupName === 'main') { // Generate package.json const packageJson: PackageJson = { @@ -856,6 +862,14 @@ export default (args: Record): rollup.RollupOptions[] => { types: './extensions.d.ts', default: './extensions.js' }, + './assets': { + types: './assets.d.ts', + default: './assets.js' + }, + './lifecycle': { + types: './lifecycle.d.ts', + default: './lifecycle.js' + }, './service-override/*': { types: './service-override/*.d.ts', default: './service-override/*.js' @@ -866,6 +880,9 @@ export default (args: Record): rollup.RollupOptions[] => { './monaco': { types: './monaco.d.ts', default: './monaco.js' + }, + './vscode/*': { + default: './vscode/src/*.js' } }, typesVersions: { @@ -881,6 +898,15 @@ export default (args: Record): rollup.RollupOptions[] => { ], monaco: [ './monaco.d.ts' + ], + assets: [ + './assets.d.ts' + ], + lifecycle: [ + './lifecycle.d.ts' + ], + 'vscode/*': [ + './vscode/src/*.d.ts' ] } }, @@ -921,27 +947,7 @@ export default (args: Record): rollup.RollupOptions[] => { ...Object.fromEntries(Object.entries(pkg.dependencies).filter(([key]) => dependencies.has(key))) } } - - const reexportFrom = `vscode/${path.relative(options.dir!, serviceOverrideEntryPoint).slice(0, -3)}` - - const entrypointInfo = this.getModuleInfo(serviceOverrideEntryPoint)! - const codeLines: string[] = [] - if ((entrypointInfo.exports ?? []).includes('default')) { - codeLines.push(`export { default } from '${reexportFrom}'`) - } - if ((entrypointInfo.exports ?? []).some(e => e !== 'default')) { - codeLines.push(`export * from '${reexportFrom}'`) - } - if ((entrypointInfo.exports ?? []).length === 0) { - codeLines.push(`import '${reexportFrom}'`) - } - await fsPromise.writeFile(path.resolve(directory, 'index.js'), codeLines.join('\n')) - await fsPromise.writeFile(path.resolve(directory, 'index.d.ts'), codeLines.join('\n')) - if (workerEntryPoint != null) { - const workerFrom = `vscode/${path.relative(options.dir!, workerEntryPoint).slice(0, -3)}` - await fsPromise.writeFile(path.resolve(directory, 'worker.js'), `import '${workerFrom}'`) - packageJson.exports = { '.': { default: './index.js' @@ -952,10 +958,123 @@ export default (args: Record): rollup.RollupOptions[] => { } } - await fsPromise.writeFile(path.resolve(directory, 'package.json'), JSON.stringify(packageJson, null, 2)) + const entrypointInfo = this.getModuleInfo(serviceOverrideEntryPoint)! + + const groupBundle = await rollup.rollup({ + input: { + index: 'entrypoint', + ...(workerEntryPoint != null + ? { + worker: 'worker' + } + : {}) + }, + external, + plugins: [ + importMetaAssets({ + include: ['**/*.ts', '**/*.js'], + // assets are externals and this plugin is not able to ignore external assets + exclude: ['**/service-override/textmate.js', '**/service-override/languageDetectionWorker.js'] + }), + nodeResolve({ + extensions: EXTENSIONS + }), { + name: 'loader', + resolveId (source, importer) { + if (source === 'entrypoint' || source === 'worker') { + return source + } + if (source.startsWith('monaco-editor/')) { + return null + } + const importerDir = path.dirname(path.resolve(DIST_DIR_MAIN, importer ?? '/')) + const resolved = path.resolve(importerDir, source) + const resolvedWithExtension = resolved.endsWith('.js') ? resolved : `${resolved}.js` + + const isNotExclusive = (resolved.startsWith(VSCODE_SRC_DIST_DIR) || path.dirname(resolved) === path.resolve(DIST_DIR_MAIN, 'service-override')) && !exclusiveModules.has(resolvedWithExtension) + const shouldBeShared = resolvedWithExtension === path.resolve(DIST_DIR_MAIN, 'assets.js') || resolvedWithExtension === path.resolve(DIST_DIR_MAIN, 'lifecycle.js') + + if (isNotExclusive || shouldBeShared) { + // Those modules will be imported from external monaco-vscode-api + let externalResolved = resolved.startsWith(VSCODE_SRC_DIST_DIR) ? `vscode/vscode/${path.relative(VSCODE_SRC_DIST_DIR, resolved)}` : `vscode/${path.relative(DIST_DIR_MAIN, resolved)}` + if (externalResolved.endsWith('.js')) { + externalResolved = externalResolved.slice(0, -3) + } + return { + id: externalResolved, + external: true + } + } + + return undefined + }, + load (id) { + if (id === 'entrypoint') { + const codeLines: string[] = [] + if ((entrypointInfo.exports ?? []).includes('default')) { + codeLines.push(`export { default } from '${serviceOverrideEntryPoint.slice(0, -3)}'`) + } + if ((entrypointInfo.exports ?? []).some(e => e !== 'default')) { + codeLines.push(`export * from '${serviceOverrideEntryPoint.slice(0, -3)}'`) + } + if ((entrypointInfo.exports ?? []).length === 0) { + codeLines.push(`import '${serviceOverrideEntryPoint.slice(0, -3)}'`) + } + return codeLines.join('\n') + } + if (id === 'worker') { + return `import '${workerEntryPoint}'` + } + if (id.startsWith('vscode/')) { + return (bundle[path.relative('vscode', id)] as rollup.OutputChunk | undefined)?.code + } + return (bundle[path.relative(DIST_DIR_MAIN, id)] as rollup.OutputChunk | undefined)?.code + }, + resolveFileUrl (options) { + let relativePath = options.relativePath + if (!relativePath.startsWith('.')) { + relativePath = `./${options.relativePath}` + } + return `'${relativePath}'` + }, + generateBundle () { + this.emitFile({ + fileName: 'package.json', + needsCodeReference: false, + source: JSON.stringify(packageJson, null, 2), + type: 'asset' + }) + } + }] + }) + await groupBundle.write({ + preserveModules: true, + preserveModulesRoot: path.resolve(DIST_DIR, 'main/service-override'), + minifyInternalExports: false, + assetFileNames: 'assets/[name][extname]', + format: 'esm', + dir: directory, + entryFileNames: '[name].js', + chunkFileNames: '[name].js', + hoistTransitiveImports: false + }) + await groupBundle.close() + + // remove exclusive files from main bundle to prevent them from being duplicated + for (const exclusiveModule of exclusiveModules) { + delete bundle[path.relative(DIST_DIR_MAIN, exclusiveModule)] + } } } - }) + }), { + name: 'clean-src', + async generateBundle () { + // Delete intermediate sources because writing to make sur there is no unused files + await fsPromise.rm(DIST_DIR_MAIN, { + recursive: true + }) + } + } ] }]) } diff --git a/rollup/rollup.default-extensions.ts b/rollup/rollup.default-extensions.ts index 3b640403..eabe7a5f 100644 --- a/rollup/rollup.default-extensions.ts +++ b/rollup/rollup.default-extensions.ts @@ -113,7 +113,7 @@ export default rollup.defineConfig([ } }), metadataPlugin({ - handle (_, dependencies, entrypoints, options, bundle) { + handle (_, dependencies, entrypoints, exclusiveModules, options, bundle) { const entrypoint = Object.values(bundle).filter(v => (v as rollup.OutputChunk).isEntry)[0]!.fileName const packageJson: PackageJson = { name: `@codingame/monaco-vscode-${name}-default-extension`, @@ -182,7 +182,7 @@ ${extensions.map(name => ` whenReady${pascalCase(name)}()`).join(',\n')} } }, metadataPlugin({ - handle (_, dependencies, entrypoints, options, bundle) { + handle (_, dependencies, entrypoints, exclusiveModules, options, bundle) { const entrypoint = Object.values(bundle).filter(v => (v as rollup.OutputChunk).isEntry)[0]!.fileName const packageJson: PackageJson = { name, diff --git a/rollup/rollup.types.config.ts b/rollup/rollup.types.config.ts index 2c3d5312..fa956b2c 100644 --- a/rollup/rollup.types.config.ts +++ b/rollup/rollup.types.config.ts @@ -1,9 +1,14 @@ import * as rollup from 'rollup' import dts from 'rollup-plugin-dts' import * as tsMorph from 'ts-morph' +import { paramCase } from 'param-case' +import { createFSBackedSystem } from '@typescript/vfs' +import ts from 'typescript' import * as path from 'path' import { fileURLToPath } from 'url' import * as fs from 'fs' +import * as fsPromise from 'fs/promises' +import metadataPlugin from './rollup-metadata-plugin' const __dirname = path.dirname(fileURLToPath(import.meta.url)) @@ -14,9 +19,49 @@ const project = new tsMorph.Project({ } }) -const VSCODE_DIR = path.join(__dirname, '../vscode') +const PROJECT_ROOT = path.join(__dirname, '..') +const VSCODE_DIR = path.join(PROJECT_ROOT, 'vscode') const VSCODE_SRC_DIR = path.join(VSCODE_DIR, 'src') -const DIST_DIR = path.join(__dirname, '../dist') +const VSCODE_SRC_DTS_DIR = path.join(VSCODE_SRC_DIR, 'vscode-dts') +const DIST_DIR = path.join(PROJECT_ROOT, 'dist') +const DIST_DIR_MAIN = path.resolve(DIST_DIR, 'main') +const DIST_DIR_VSCODE_SRC_MAIN = path.resolve(DIST_DIR_MAIN, 'vscode/src') +const TYPES_SRC_DIR = path.join(DIST_DIR, 'types/src') +const SERVICE_OVERRIDE_DIR = path.join(TYPES_SRC_DIR, 'service-override') +const SERVICE_OVERRIDE_DIST_DIR = path.join(DIST_DIR_MAIN, 'service-override') + +function getProposedVscodeTypes () { + const proposedTypes = fs.readdirSync(VSCODE_SRC_DTS_DIR).filter(f => f !== 'vscode.d.ts').map(f => { + const [sourceFile] = project.addSourceFilesAtPaths(path.resolve(VSCODE_SRC_DTS_DIR, f)) + for (const module of sourceFile!.getModules()) { + for (const exportable of [ + ...module.getInterfaces(), + ...module.getEnums(), + ...module.getClasses(), + ...module.getFunctions(), + ...module.getVariableStatements() + ]) { + exportable.setIsExported(true) + } + } + return sourceFile!.getModules().map(module => module.getBodyText()).join('\n') + }).join('\n') + + const [mainVscodeTypes] = project.addSourceFilesAtPaths(path.resolve(VSCODE_SRC_DTS_DIR, 'vscode.d.ts')) + const exported = mainVscodeTypes!.getModules().flatMap(module => Array.from(module.getExportedDeclarations().keys())) + return `export * from 'vscode'\nimport { ${exported.join(', ')} } from 'vscode'\n\n${proposedTypes}` +} + +// create a virtual filesystem for typescript so we don't have to write the temporary file on the disk +const typescriptFilesystemOverride = new Map() +typescriptFilesystemOverride.set(path.resolve(PROJECT_ROOT, 'vscode-proposed.d.ts'), getProposedVscodeTypes()) +// For some reasons, the `setSys` method is not exposed +// eslint-disable-next-line @typescript-eslint/no-explicit-any +;(ts as any).setSys(createFSBackedSystem(typescriptFilesystemOverride, PROJECT_ROOT, ts)) +// This method is not implemented in @typescript/vfs and it makes the build crash +ts.sys.getExecutingFilePath = () => { + return PROJECT_ROOT +} const interfaceOverride = new Map() interfaceOverride.set('Event', 'vscode.Event') @@ -31,55 +76,178 @@ interfaceOverride.set('IStandaloneDiffEditor', 'monaco.editor.IStandaloneDiffEdi interfaceOverride.set('IStandaloneEditorConstructionOptions', 'monaco.editor.IStandaloneEditorConstructionOptions') interfaceOverride.set('IStandaloneDiffEditorConstructionOptions', 'monaco.editor.IStandaloneDiffEditorConstructionOptions') -export default rollup.defineConfig([{ - input: [ - './dist/types/src/services.d.ts', - './dist/types/src/extensions.d.ts', - ...fs.readdirSync(path.resolve(DIST_DIR, 'types/src/service-override'), { withFileTypes: true }) +function isExternal (id: string, main: boolean) { + if (id.endsWith('.css')) { + return true + } + if (id.includes('.contribution')) { + return true + } + if (main) { + return [ + 'vscode', 'monaco-editor', 'tas-client-umd' + ].includes(id) + } + + return [ + 'vscode', 'monaco-editor', 'tas-client-umd', 'vscode-textmate', 'rollup', '@rollup/pluginutils', + 'xterm', 'xterm-addon-canvas', 'xterm-addon-search', 'xterm-addon-unicode11', + 'xterm-addon-webgl', 'xterm-addon-serialize', 'xterm-addon-image', 'xterm-headless' + ].some(external => id === external || id.startsWith(`${external}/`)) +} + +export default rollup.defineConfig((<{input: Record, output: string, preserveModulesRoot?: string, main?: boolean}[]>[{ + input: { + 'services.d': './dist/types/src/services.d.ts', + 'extensions.d': './dist/types/src/extensions.d.ts', + 'monaco.d': './dist/types/src/monaco.d.ts', + ...Object.fromEntries(fs.readdirSync(path.resolve(DIST_DIR, 'types/src/service-override'), { withFileTypes: true }) .filter(f => f.isFile()) .map(f => f.name) - .map(name => `./dist/types/src/service-override/${name}`), - './dist/types/src/monaco.d.ts' - ], - output: 'dist/main' + .map(name => [ + `service-override/${path.basename(name, '.ts')}`, `./dist/types/src/service-override/${name}` + ])) + }, + output: 'dist/main', + main: true }, { - input: [ - './dist/types/src/rollup-vsix-plugin.d.ts' - ], + input: { + 'rollup-vsix-plugin.d': './dist/types/src/rollup-vsix-plugin.d.ts' + }, output: 'dist/rollup-vsix-plugin' }, { - input: [ - './dist/types/src/rollup-extension-directory-plugin.d.ts' - ], + input: { + 'rollup-extension-directory-plugin.d': './dist/types/src/rollup-extension-directory-plugin.d.ts' + }, output: 'dist/rollup-extension-directory-plugin' -}].map(({ input, output }) => ({ - input: Object.fromEntries(input.map(input => ([ - path.relative(path.resolve(DIST_DIR, 'types/src'), path.resolve(__dirname, '..', input)).slice(0, -3), - input - ]))), +}]).map(({ input, output, preserveModulesRoot = TYPES_SRC_DIR, main = false }) => ({ + input, + treeshake: false, output: { preserveModules: true, - preserveModulesRoot: 'dist/types/src', + preserveModulesRoot, format: 'esm', dir: output, - entryFileNames: chunk => `${chunk.name}.ts`, - chunkFileNames: chunk => `${chunk.name}.ts`, - assetFileNames: chunk => `${chunk.name}.ts` - }, - external: function isExternal (id) { - if (id.endsWith('.css')) { - return true - } - if (id.includes('.contribution')) { - return true + entryFileNames: (chunkInfo) => { + // Rename node_modules to external so it's not removing while publishing the package + // tslib and rollup-plugin-styles and bundled + if (chunkInfo.name.includes('node_modules')) { + return chunkInfo.name.replace('node_modules', 'external') + '.ts' + } + return '[name].ts' } - return [ - 'vscode', 'monaco-editor', 'vscode-textmate', 'rollup', '@rollup/pluginutils', - 'xterm', 'tas-client-umd', 'xterm-addon-canvas', 'xterm-addon-search', 'xterm-addon-unicode11', - 'xterm-addon-webgl', 'xterm-addon-serialize', 'xterm-addon-image', 'xterm-headless' - ].includes(id) }, + external: (id) => isExternal(id, main), plugins: [ + metadataPlugin({ + stage: 'writeBundle', // rollup-plugin-dts needs the file to exist on the disk + getGroup (id: string) { + if (id.startsWith(SERVICE_OVERRIDE_DIR)) { + return path.basename(id, '.d.ts') + } + return 'main' + }, + async handle (groupName, dependencies, exclusiveModules, entrypoints, options, bundle) { + if (groupName === 'main') { + return + } + + const serviceOverrideEntryPoint = Array.from(entrypoints)[0]! + const entrypointInfo = this.getModuleInfo(serviceOverrideEntryPoint)! + + const groupBundle = await rollup.rollup({ + input: { + 'index.d': 'entrypoint' + }, + external: (id) => { + if (id === 'vscode') { + // we need to load the proposed types of vscode, so let says it's not external and override the load method to load the proposed types + return undefined + } + return isExternal(id, main) + }, + plugins: [ + { + name: 'loader', + resolveId (source, importer) { + if (source === 'entrypoint') { + return source + } + if (source.startsWith('monaco-editor/')) { + return null + } + if (source === 'vscode') { + if (!importer!.includes('vscode-proposed.d.ts')) { + return path.resolve(PROJECT_ROOT, 'vscode-proposed.d.ts') + } else { + return { + id: 'vscode', + external: true + } + } + } + const importerDir = path.dirname(path.resolve(DIST_DIR_MAIN, importer ?? '/')) + const resolved = path.resolve(importerDir, source) + const resolvedWithoutExtension = resolved.endsWith('.js') ? resolved.slice(0, -3) : resolved + const resolvedWithExtension = resolvedWithoutExtension.endsWith('.d.ts') ? resolvedWithoutExtension : `${resolvedWithoutExtension}.d.ts` + + const isNotExclusive = (resolved.startsWith(path.resolve(DIST_DIR_MAIN, 'vscode')) || path.dirname(resolved) === path.resolve(DIST_DIR_MAIN, 'service-override')) && !exclusiveModules.has(resolvedWithExtension) + + if (isNotExclusive) { + // Those modules will be imported from external monaco-vscode-api + const externalResolved = resolved.startsWith(DIST_DIR_VSCODE_SRC_MAIN) ? `vscode/vscode/${path.relative(DIST_DIR_VSCODE_SRC_MAIN, resolvedWithoutExtension)}` : `vscode/${path.relative(DIST_DIR_MAIN, resolvedWithoutExtension)}` + return { + id: externalResolved, + external: true + } + } + + return undefined + }, + load (id) { + if (id === 'entrypoint') { + const serviceOverrideTypesPath = `${path.resolve(SERVICE_OVERRIDE_DIST_DIR, groupName)}` + const codeLines: string[] = [] + if ((entrypointInfo.exports ?? []).includes('default')) { + codeLines.push(`export { default } from '${serviceOverrideTypesPath}'`) + } + if ((entrypointInfo.exports ?? []).some(e => e !== 'default')) { + codeLines.push(`export * from '${serviceOverrideTypesPath}'`) + } + return codeLines.join('\n') + } + if (typescriptFilesystemOverride.has(id)) { + return typescriptFilesystemOverride.get(id) + } + if (id.startsWith('vscode/')) { + return (bundle[path.relative('vscode', id)] as rollup.OutputChunk | undefined)?.code + } + return (bundle[path.relative(DIST_DIR_MAIN, id)] as rollup.OutputChunk | undefined)?.code + } + }, + dts({ + respectExternal: true + }) + ] + }) + await groupBundle.write({ + preserveModules: true, + preserveModulesRoot: path.resolve(DIST_DIR, 'main/service-override'), + minifyInternalExports: false, + assetFileNames: 'assets/[name][extname]', + format: 'esm', + dir: path.resolve(DIST_DIR, `service-override-${paramCase(groupName)}`), + entryFileNames: '[name].ts', + hoistTransitiveImports: false + }) + await groupBundle.close() + + // remove exclusive files from main bundle to prevent them from being duplicated + await Promise.all(Array.from(exclusiveModules).filter(m => m.startsWith(DIST_DIR_MAIN)).map(async module => { + await fsPromise.rm(module) + })) + } + }), { name: 'change-unsupported-syntax', transform (code) { @@ -91,16 +259,28 @@ export default rollup.defineConfig([{ load (id) { const path = new URL(id, 'file:/').pathname const [sourceFile] = project.addSourceFilesAtPaths(path) + if (sourceFile == null) { + return undefined + } + + if (id.includes('node_modules') && id.includes('xterm')) { + // xterm modules use `declare module` syntax not supposed by the rollup-dts-plugin, so let's transform the code + const module = sourceFile.getModules()[0]! + for (const _interface of module.getInterfaces()) { + _interface.setIsExported(true) + } + return `${sourceFile.getImportDeclarations().map(e => e.getText()).join('\n')}\n${module.getBodyText()}` + } - sourceFile!.addImportDeclaration({ + sourceFile.addImportDeclaration({ moduleSpecifier: 'monaco-editor', namespaceImport: 'monaco' }) - sourceFile!.addImportDeclaration({ + sourceFile.addImportDeclaration({ moduleSpecifier: 'vscode', namespaceImport: 'vscode' }) - return sourceFile!.getFullText() + return sourceFile.getFullText() }, transform (code, id) { interfaceOverride.forEach((value, key) => { @@ -127,7 +307,7 @@ export default rollup.defineConfig([{ if (importee.startsWith('vscode/')) { return path.resolve(VSCODE_DIR, path.relative('vscode', `${importee}.d.ts`)) } - if (!importee.startsWith('vs/') && importer != null && importer.startsWith(VSCODE_SRC_DIR)) { + if (importee.startsWith('.') && importer != null && importer.startsWith(VSCODE_SRC_DIR)) { importee = path.relative(VSCODE_SRC_DIR, path.resolve(path.dirname(importer), importee)) } if (importee.startsWith('vs/')) { diff --git a/scripts/generate-types b/scripts/generate-types index 4eb40f18..3afba90c 100755 --- a/scripts/generate-types +++ b/scripts/generate-types @@ -5,7 +5,7 @@ set -e tsc --project tsconfig.types.json # bundle them with rollup -rollup --config rollup/rollup.types.config.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-types.json`}' +NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.types.config.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-types.json`}' # remove temporary files rm -rf ./dist/types diff --git a/src/extensions.ts b/src/extensions.ts index 064ebc1b..2dfb184e 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -89,9 +89,9 @@ async function deltaExtensions (toAdd: IExtensionWithExtHostKind[], toRemove: IE await lastPromise } -export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalProcess, params: RegisterExtensionParams): RegisterLocalProcessExtensionResult -export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalWebWorker, params: RegisterExtensionParams): RegisterLocalExtensionResult -export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.Remote, params: RegisterRemoteExtensionParams): RegisterRemoteExtensionResult +export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalProcess, params?: RegisterExtensionParams): RegisterLocalProcessExtensionResult +export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.LocalWebWorker, params?: RegisterExtensionParams): RegisterLocalExtensionResult +export function registerExtension (manifest: IExtensionManifest, extHostKind: ExtensionHostKind.Remote, params?: RegisterRemoteExtensionParams): RegisterRemoteExtensionResult export function registerExtension (manifest: IExtensionManifest, extHostKind?: ExtensionHostKind, params?: RegisterExtensionParams): RegisterExtensionResult export function registerExtension (manifest: IExtensionManifest, extHostKind?: ExtensionHostKind, { defaultNLS, builtin = manifest.publisher === 'vscode', path = '/' }: RegisterExtensionParams = {}): RegisterExtensionResult { const disposableStore = new DisposableStore() diff --git a/src/missing-services.ts b/src/missing-services.ts index e8f6fa3e..43eda311 100644 --- a/src/missing-services.ts +++ b/src/missing-services.ts @@ -352,7 +352,7 @@ class EmptyEditorGroup implements IEditorGroup, IEditorGroupView { } const fakeActiveGroup = new EmptyEditorGroup() -export class EmptyEditorGroupsService implements IEditorGroupsService { +class EmptyEditorGroupsService implements IEditorGroupsService { readonly _serviceBrand = undefined getLayout = unsupported onDidChangeActiveGroup = Event.None diff --git a/src/service-override/accessibility.ts b/src/service-override/accessibility.ts index d27cfa57..043adb2d 100644 --- a/src/service-override/accessibility.ts +++ b/src/service-override/accessibility.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { AccessibleViewService, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView' diff --git a/src/service-override/audioCue.ts b/src/service-override/audioCue.ts index 264e66aa..4eb64dbd 100644 --- a/src/service-override/audioCue.ts +++ b/src/service-override/audioCue.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { AudioCueService, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService' diff --git a/src/service-override/bulkEdit.ts b/src/service-override/bulkEdit.ts index 78caa800..39b14e1e 100644 --- a/src/service-override/bulkEdit.ts +++ b/src/service-override/bulkEdit.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService' diff --git a/src/service-override/configuration.ts b/src/service-override/configuration.ts index 9f62823a..bf07e07d 100644 --- a/src/service-override/configuration.ts +++ b/src/service-override/configuration.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService' import { IConfigurationService } from 'vs/platform/configuration/common/configuration' diff --git a/src/service-override/debug.ts b/src/service-override/debug.ts index 6f7ce7d6..f67caf62 100644 --- a/src/service-override/debug.ts +++ b/src/service-override/debug.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IDebugService } from 'vs/workbench/contrib/debug/common/debug' diff --git a/src/service-override/dialogs.ts b/src/service-override/dialogs.ts index fc7777d7..99c99709 100644 --- a/src/service-override/dialogs.ts +++ b/src/service-override/dialogs.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import 'vs/workbench/browser/parts/dialogs/dialog.web.contribution' import { DialogService } from 'vs/workbench/services/dialogs/common/dialogService' diff --git a/src/service-override/editor.ts b/src/service-override/editor.ts index d823dfc5..1ec42bc8 100644 --- a/src/service-override/editor.ts +++ b/src/service-override/editor.ts @@ -1,4 +1,5 @@ -import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' +import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' +import { Event } from 'vs/base/common/event' import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService' import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService' import { CodeEditorService } from 'vs/workbench/services/editor/browser/codeEditorService' @@ -10,13 +11,136 @@ import { IReference } from 'vs/base/common/lifecycle' import { ITextEditorService, TextEditorService } from 'vs/workbench/services/textfile/common/textEditorService' import { Registry } from 'vs/platform/registry/common/platform' import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files' -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService' +import { GroupOrientation, IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService' import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey' +import { IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor' import { MonacoDelegateEditorGroupsService, MonacoEditorService, OpenEditor } from './tools/editor' import { unsupported } from '../tools' -import { EmptyEditorGroupsService } from '../missing-services' import 'vs/workbench/browser/parts/editor/editor.contribution' +class EmptyEditorGroup implements IEditorGroup, IEditorGroupView { + onDidFocus = Event.None + onDidOpenEditorFail = Event.None + whenRestored = Promise.resolve() + get titleHeight () { + return unsupported() + } + + disposed = false + setActive = unsupported + notifyIndexChanged = unsupported + relayout = unsupported + dispose = unsupported + toJSON = unsupported + preferredWidth?: number | undefined + preferredHeight?: number | undefined + get element () { + return unsupported() + } + + minimumWidth = 0 + maximumWidth = Number.POSITIVE_INFINITY + minimumHeight = 0 + maximumHeight = Number.POSITIVE_INFINITY + onDidChange = Event.None + layout = unsupported + onDidModelChange = Event.None + onWillDispose = Event.None + onDidActiveEditorChange = Event.None + onWillCloseEditor = Event.None + onDidCloseEditor = Event.None + onWillMoveEditor = Event.None + onWillOpenEditor = Event.None + id = 0 + index = 0 + label = 'main' + ariaLabel = 'main' + activeEditorPane = undefined + activeEditor = null + previewEditor = null + count = 0 + isEmpty = false + isLocked = false + stickyCount = 0 + editors = [] + get scopedContextKeyService (): IContextKeyService { return StandaloneServices.get(IContextKeyService) } + getEditors = () => [] + findEditors = () => [] + getEditorByIndex = () => undefined + getIndexOfEditor = unsupported + openEditor = unsupported + openEditors = unsupported + isPinned = () => false + isSticky = () => false + isActive = () => false + contains = () => false + moveEditor = unsupported + moveEditors = unsupported + copyEditor = unsupported + copyEditors = unsupported + closeEditor = unsupported + closeEditors = unsupported + closeAllEditors = unsupported + replaceEditors = unsupported + pinEditor = unsupported + stickEditor = unsupported + unstickEditor = unsupported + lock = unsupported + focus (): void { + // ignore + } + + isFirst = unsupported + isLast = unsupported +} + +const fakeActiveGroup = new EmptyEditorGroup() + +class EmptyEditorGroupsService implements IEditorGroupsService { + readonly _serviceBrand = undefined + getLayout = unsupported + onDidChangeActiveGroup = Event.None + onDidAddGroup = Event.None + onDidRemoveGroup = Event.None + onDidMoveGroup = Event.None + onDidActivateGroup = Event.None + onDidLayout = Event.None + onDidScroll = Event.None + onDidChangeGroupIndex = Event.None + onDidChangeGroupLocked = Event.None + get contentDimension (): never { return unsupported() } + activeGroup = fakeActiveGroup + get sideGroup (): never { return unsupported() } + groups = [fakeActiveGroup] + count = 0 + orientation = GroupOrientation.HORIZONTAL + isReady = false + whenReady = Promise.resolve() + whenRestored = Promise.resolve() + hasRestorableState = false + getGroups = (): never[] => [] + getGroup = (): undefined => undefined + activateGroup = unsupported + getSize = unsupported + setSize = unsupported + arrangeGroups = unsupported + applyLayout = unsupported + centerLayout = unsupported + isLayoutCentered = (): boolean => false + setGroupOrientation = unsupported + findGroup = (): undefined => undefined + addGroup = unsupported + removeGroup = unsupported + moveGroup = unsupported + mergeGroup = unsupported + mergeAllGroups = unsupported + copyGroup = unsupported + partOptions = {} + onDidChangeEditorPartOptions = Event.None + enforcePartOptions = unsupported +} + class MonacoEditorGroupsService extends MonacoDelegateEditorGroupsService { constructor (@IInstantiationService instantiationService: IInstantiationService) { super( diff --git a/src/service-override/environment.ts b/src/service-override/environment.ts index 17c077d2..e367a854 100644 --- a/src/service-override/environment.ts +++ b/src/service-override/environment.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { BrowserWorkbenchEnvironmentService, IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService' diff --git a/src/service-override/files.ts b/src/service-override/files.ts index a26f63c1..eb89bdd3 100644 --- a/src/service-override/files.ts +++ b/src/service-override/files.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { FileService } from 'vs/platform/files/common/fileService' diff --git a/src/service-override/keybindings.ts b/src/service-override/keybindings.ts index 70a137d5..9268d68f 100644 --- a/src/service-override/keybindings.ts +++ b/src/service-override/keybindings.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { WorkbenchKeybindingService } from 'vs/workbench/services/keybinding/browser/keybindingService' diff --git a/src/service-override/languageDetectionWorker.ts b/src/service-override/languageDetectionWorker.ts index e65e8f33..3d26c240 100644 --- a/src/service-override/languageDetectionWorker.ts +++ b/src/service-override/languageDetectionWorker.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { LanguageDetectionService } from 'vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl' diff --git a/src/service-override/languages.ts b/src/service-override/languages.ts index 60a7580d..dc2e6fed 100644 --- a/src/service-override/languages.ts +++ b/src/service-override/languages.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { WorkbenchLanguageService } from 'vs/workbench/services/language/common/languageService' diff --git a/src/service-override/layout.ts b/src/service-override/layout.ts index d70613fc..2cc92cd9 100644 --- a/src/service-override/layout.ts +++ b/src/service-override/layout.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { IWorkbenchLayoutService, PanelAlignment, Parts, Position } from 'vs/workbench/services/layout/browser/layoutService' import { ILayoutOffsetInfo, ILayoutService } from 'vs/platform/layout/browser/layoutService' diff --git a/src/service-override/lifecycle.ts b/src/service-override/lifecycle.ts index 1b962207..ba9a8a79 100644 --- a/src/service-override/lifecycle.ts +++ b/src/service-override/lifecycle.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { BrowserLifecycleService } from 'vs/workbench/services/lifecycle/browser/lifecycleService' diff --git a/src/service-override/markers.ts b/src/service-override/markers.ts index c703ccad..9508acb0 100644 --- a/src/service-override/markers.ts +++ b/src/service-override/markers.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import 'vs/workbench/contrib/markers/browser/markers.contribution' diff --git a/src/service-override/model.ts b/src/service-override/model.ts index fc1ff143..d92be946 100644 --- a/src/service-override/model.ts +++ b/src/service-override/model.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { ITextModelService } from 'vs/editor/common/services/resolverService' import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService' diff --git a/src/service-override/notifications.ts b/src/service-override/notifications.ts index 503e3223..b0a38fad 100644 --- a/src/service-override/notifications.ts +++ b/src/service-override/notifications.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { NotificationsToasts } from 'vs/workbench/browser/parts/notifications/notificationsToasts' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' diff --git a/src/service-override/output.ts b/src/service-override/output.ts index 342e237c..188b6292 100644 --- a/src/service-override/output.ts +++ b/src/service-override/output.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { URI } from 'vs/base/common/uri' diff --git a/src/service-override/preferences.ts b/src/service-override/preferences.ts index 5127707c..eff862cf 100644 --- a/src/service-override/preferences.ts +++ b/src/service-override/preferences.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences' diff --git a/src/service-override/quickaccess.ts b/src/service-override/quickaccess.ts index 046c786c..847c4274 100644 --- a/src/service-override/quickaccess.ts +++ b/src/service-override/quickaccess.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IInputBox, IInputOptions, IPickOptions, IQuickInputButton, IQuickInputService, IQuickNavigateConfiguration, IQuickPick, IQuickPickItem, IQuickWidget, QuickPickInput } from 'vs/platform/quickinput/common/quickInput' import { CancellationToken } from 'vs/base/common/cancellation' diff --git a/src/service-override/remoteAgent.ts b/src/service-override/remoteAgent.ts index 39ee0ed2..678feb08 100644 --- a/src/service-override/remoteAgent.ts +++ b/src/service-override/remoteAgent.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService' diff --git a/src/service-override/search.ts b/src/service-override/search.ts index 02d3fd96..6b45f39b 100644 --- a/src/service-override/search.ts +++ b/src/service-override/search.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { ISearchService } from 'vs/workbench/services/search/common/search' diff --git a/src/service-override/snippets.ts b/src/service-override/snippets.ts index 8035890c..29e002c4 100644 --- a/src/service-override/snippets.ts +++ b/src/service-override/snippets.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { ISnippetsService } from 'vs/workbench/contrib/snippets/browser/snippets' diff --git a/src/service-override/terminal.ts b/src/service-override/terminal.ts index cda4eb1d..5bbf13b1 100644 --- a/src/service-override/terminal.ts +++ b/src/service-override/terminal.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IProcessReadyEvent, ITerminalBackend, ITerminalBackendRegistry, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, TerminalExtensions, ITerminalLogService, IPtyHostLatencyMeasurement } from 'vs/platform/terminal/common/terminal' diff --git a/src/service-override/textmate.ts b/src/service-override/textmate.ts index 44621074..d7b4746b 100644 --- a/src/service-override/textmate.ts +++ b/src/service-override/textmate.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { ITextMateTokenizationService } from 'vs/workbench/services/textMate/browser/textMateTokenizationFeature' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' diff --git a/src/service-override/theme.ts b/src/service-override/theme.ts index 9906e0f9..113524b9 100644 --- a/src/service-override/theme.ts +++ b/src/service-override/theme.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/workbenchThemeService' import { IThemeExtensionPoint } from 'vs/workbench/services/themes/common/workbenchThemeService' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' diff --git a/src/service-override/viewBanner.ts b/src/service-override/viewBanner.ts index 9ca51ebd..61e11541 100644 --- a/src/service-override/viewBanner.ts +++ b/src/service-override/viewBanner.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { BannerPart } from 'vs/workbench/browser/parts/banner/bannerPart' diff --git a/src/service-override/viewStatusBar.ts b/src/service-override/viewStatusBar.ts index 7b03f744..3ad8a223 100644 --- a/src/service-override/viewStatusBar.ts +++ b/src/service-override/viewStatusBar.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { StatusbarPart } from 'vs/workbench/browser/parts/statusbar/statusbarPart' diff --git a/src/service-override/viewTitleBar.ts b/src/service-override/viewTitleBar.ts index ef30f400..c7a65016 100644 --- a/src/service-override/viewTitleBar.ts +++ b/src/service-override/viewTitleBar.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { ITitleService } from 'vs/workbench/services/title/common/titleService' diff --git a/src/service-override/views.ts b/src/service-override/views.ts index 9d98b525..4b64d70c 100644 --- a/src/service-override/views.ts +++ b/src/service-override/views.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IViewContainersRegistry, IViewDescriptor, IViewDescriptorService, IViewsRegistry, IViewsService, ViewContainerLocation, Extensions as ViewExtensions } from 'vs/workbench/common/views' diff --git a/src/service-override/workspaceTrust.ts b/src/service-override/workspaceTrust.ts index 76c792e9..30c2804a 100644 --- a/src/service-override/workspaceTrust.ts +++ b/src/service-override/workspaceTrust.ts @@ -1,4 +1,3 @@ -import '../missing-services' import { IEditorOverrideServices } from 'vs/editor/standalone/browser/standaloneServices' import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors' import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust' diff --git a/src/services.ts b/src/services.ts index c07a1d16..f8067e9a 100644 --- a/src/services.ts +++ b/src/services.ts @@ -1,3 +1,4 @@ +import './missing-services' import Severity from 'vs/base/common/severity' import { IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration' import { ITextModelContentProvider } from 'vs/editor/common/services/resolverService' @@ -6,6 +7,7 @@ import { StorageScope, StorageTarget } from 'vscode/src/vs/platform/storage/comm import { IEditorOverrideServices, StandaloneServices } from 'vs/editor/standalone/browser/standaloneServices' import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation' import { IAction } from 'vs/base/common/actions' +import { Disposable } from 'vs/base/common/lifecycle' import getLayoutServiceOverride from './service-override/layout' import getEnvironmentServiceOverride from './service-override/environment' import getExtensionsServiceOverride from './service-override/extensions' @@ -13,7 +15,16 @@ import getFileServiceOverride from './service-override/files' import getQuickAccessOverride from './service-override/quickaccess' import { serviceInitializedBarrier, startup } from './lifecycle' +let servicesInitialized = false +StandaloneServices.withServices(() => { + servicesInitialized = true + return Disposable.None +}) + export async function initialize (overrides: IEditorOverrideServices, container?: HTMLElement): Promise { + if (servicesInitialized) { + throw new Error('The services are already initialized.') + } const instantiationService = StandaloneServices.initialize({ ...getLayoutServiceOverride(container), // Always override layout service to break cyclic dependency with ICodeEditorService ...getEnvironmentServiceOverride(),