diff --git a/package-lock.json b/package-lock.json index 98659d9d..f8d86987 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,6 +91,7 @@ "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.4.1", "semantic-release": "25.0.3", + "ts-morph": "^28.0.0", "tsx": "^4.21.0", "type-fest": "^5.5.0", "typescript": "^5.9.3", @@ -4265,6 +4266,57 @@ "node": ">= 10" } }, + "node_modules/@ts-morph/common": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.29.0.tgz", + "integrity": "sha512-35oUmphHbJvQ/+UTwFNme/t2p3FoKiGJ5auTjjpNTop2dyREspirjMy82PLSC1pnDJ8ah1GU98hwpVt64YXQsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1", + "tinyglobby": "^0.2.14" + } + }, + "node_modules/@ts-morph/common/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@types/conventional-commits-parser": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.2.tgz", @@ -5661,6 +5713,13 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "dev": true, + "license": "MIT" + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -11358,6 +11417,13 @@ "node": ">=10" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -13200,6 +13266,17 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-morph": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-28.0.0.tgz", + "integrity": "sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.29.0", + "code-block-writer": "^13.0.3" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", diff --git a/package.json b/package.json index 78e2030a..aae59641 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ }, "type": "module", "scripts": { - "build": "npm run clean && npm run lint && npm run compile && npm run compile-rollup-plugins && npm run compile-default-extensions && npm run compile-language-packs && npm run compile-monaco-languages", + "build": "npm run clean && npm run lint && npm run check-unsupported-decorator && npm run compile && npm run compile-rollup-plugins && npm run compile-default-extensions && npm run compile-language-packs && npm run compile-monaco-languages", "compile": "NODE_OPTIONS=--max_old_space_size=16384 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} --vscode-commit ${npm_package_config_vscode_commit}", "compile-default-extensions": "NODE_OPTIONS=--max_old_space_size=16384 rollup --config rollup/rollup.default-extensions.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-default-extensions.json`}'", "compile-language-packs": "NODE_OPTIONS=--max_old_space_size=16384 rollup --config rollup/rollup.language-packs.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-language-packs.json`}'", @@ -26,7 +26,8 @@ "lint": "eslint '{src/**/*.ts,rollup/*.ts,*.ts}'", "update-vscode-dependencies": "tsx scripts/update-vscode-dependencies.ts", "release": "tsx release.ts", - "reset:repo": "git clean -f -X -d" + "reset:repo": "git clean -f -X -d", + "check-unsupported-decorator": "tsx scripts/check-unsupported-decorator.ts" }, "config": { "vscode": { @@ -80,6 +81,7 @@ "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.4.1", "semantic-release": "25.0.3", + "ts-morph": "^28.0.0", "tsx": "^4.21.0", "type-fest": "^5.5.0", "typescript": "^5.9.3", diff --git a/scripts/check-unsupported-decorator.ts b/scripts/check-unsupported-decorator.ts new file mode 100644 index 00000000..2c435cdb --- /dev/null +++ b/scripts/check-unsupported-decorator.ts @@ -0,0 +1,29 @@ +import { Project } from 'ts-morph' + +const project = new Project({ tsConfigFilePath: 'tsconfig.json' }) +const sourceFile = project.getSourceFileOrThrow('src/missing-services.ts') + +const issues: string[] = [] + +for (const cls of sourceFile.getClasses()) { + for (const prop of cls.getProperties()) { + const initText = prop.getInitializer()?.getText().trim() + const usesUnsupported = initText === 'unsupported' + const hasDecorator = prop.getDecorator('Unsupported') != null + + const loc = `${cls.getName()}.${prop.getName()} (line ${prop.getStartLineNumber()})` + + if (usesUnsupported && !hasDecorator) { + issues.push(`❌ ${loc}: uses \`unsupported\` but is missing the @Unsupported decorator`) + } + if (!usesUnsupported && hasDecorator) { + issues.push(`❌ ${loc}: has @Unsupported decorator but does not use \`unsupported\``) + } + } +} + +if (issues.length) { + console.error(issues.join('\n')) + process.exit(1) +} +console.log('✅ All consistent') \ No newline at end of file diff --git a/src/missing-services.ts b/src/missing-services.ts index 5252e162..3d606268 100644 --- a/src/missing-services.ts +++ b/src/missing-services.ts @@ -2066,11 +2066,8 @@ class ExtensionsScannerService implements IExtensionsScannerService { return unsupported() } onDidChangeCache: IExtensionsScannerService['onDidChangeCache'] = Event.None - @Unsupported scanAllExtensions: IExtensionsScannerService['scanAllExtensions'] = async () => [] - @Unsupported scanSystemExtensions: IExtensionsScannerService['scanSystemExtensions'] = async () => [] - @Unsupported scanUserExtensions: IExtensionsScannerService['scanUserExtensions'] = async () => [] @Unsupported scanExtensionsUnderDevelopment: IExtensionsScannerService['scanExtensionsUnderDevelopment'] = @@ -2725,7 +2722,6 @@ class TerminalService implements ITerminalService { createTerminal: ITerminalService['createTerminal'] = unsupported @Unsupported getInstanceFromId: ITerminalService['getInstanceFromId'] = unsupported - @Unsupported getReconnectedTerminals: ITerminalService['getReconnectedTerminals'] = () => undefined @Unsupported getActiveOrCreateInstance: ITerminalService['getActiveOrCreateInstance'] = unsupported @@ -4100,7 +4096,6 @@ class AuthenticationService implements IAuthenticationService { getProviderIds: IAuthenticationService['getProviderIds'] = () => [] @Unsupported getProvider: IAuthenticationService['getProvider'] = unsupported - @Unsupported getSessions: IAuthenticationService['getSessions'] = async () => [] @Unsupported createSession: IAuthenticationService['createSession'] = unsupported @@ -5669,7 +5664,6 @@ class McpRegistry implements IMcpRegistry { } @Unsupported setSavedInput: IMcpRegistry['setSavedInput'] = unsupported - @Unsupported getServerDefinition: IMcpRegistry['getServerDefinition'] = () => constObservable({ server: undefined, @@ -5740,7 +5734,6 @@ class NullDefaultAccountService extends Disposable implements IDefaultAccountSer @Unsupported getDefaultAccountAuthenticationProvider: IDefaultAccountService['getDefaultAccountAuthenticationProvider'] = unsupported - @Unsupported setDefaultAccountProvider: IDefaultAccountService['setDefaultAccountProvider'] = () => {} refresh: IDefaultAccountService['refresh'] = async () => null @Unsupported @@ -6946,6 +6939,7 @@ registerSingleton(IInlineChatHistoryService, InlineChatHistoryService, Instantia class BrowserViewWorkbenchService implements IBrowserViewWorkbenchService { _serviceBrand: undefined + @Unsupported getOrCreateBrowserViewModel: IBrowserViewWorkbenchService['getOrCreateBrowserViewModel'] = unsupported @Unsupported