@@ -9,7 +9,6 @@ import * as path from 'path';
99import archiver from 'archiver' ;
1010import { RoslynLanguageServer } from '../server/roslynLanguageServer' ;
1111import { ObservableLogOutputChannel } from './observableLogOutputChannel' ;
12- import { commonOptions , languageServerOptions , razorOptions } from '../../shared/options' ;
1312
1413/**
1514 * Registers the command to capture C# log output.
@@ -216,40 +215,66 @@ export async function readLogFileContent(logFileUri: vscode.Uri): Promise<string
216215}
217216
218217/**
219- * Gathers the current settings for CommonOptions, LanguageServerOptions, and RazorOptions.
218+ * Gathers the current VS Code settings for dotnet, csharp, razor, and omnisharp namespaces.
219+ * Reads the setting keys from the extension's package.json to enumerate all available settings.
220220 * Returns a formatted JSON string.
221221 */
222222export function gatherCurrentSettings ( ) : string {
223- const settings = {
224- commonOptions : getOptionValues ( commonOptions ) ,
225- languageServerOptions : getOptionValues ( languageServerOptions ) ,
226- razorOptions : getOptionValues ( razorOptions ) ,
223+ const extensionId = 'ms-dotnettools.csharp' ;
224+ const extension = vscode . extensions . getExtension ( extensionId ) ;
225+
226+ if ( ! extension ) {
227+ return JSON . stringify ( { error : 'Could not find C# extension' } , null , 2 ) ;
228+ }
229+
230+ // Get all configuration properties defined in package.json
231+ const packageJson = extension . packageJSON as {
232+ contributes ?: {
233+ configuration ?: Array < {
234+ properties ?: Record < string , unknown > ;
235+ } > ;
236+ } ;
227237 } ;
228- return JSON . stringify ( settings , null , 2 ) ;
229- }
230238
231- /**
232- * Extracts all option values from an options object by iterating over its property descriptors.
233- *
234- * Note: We cannot use Object.keys() here because the options objects are class instances where
235- * all properties are defined as getters on the prototype, not as own properties on the instance.
236- * Object.keys() only returns enumerable own properties, so it would return an empty array.
237- * Instead, we inspect the prototype's property descriptors to find all the getter functions.
238- */
239- function getOptionValues < T extends object > ( options : T ) : Record < string , unknown > {
240- const result : Record < string , unknown > = { } ;
241- const prototype = Object . getPrototypeOf ( options ) ;
242- const descriptors = Object . getOwnPropertyDescriptors ( prototype ) ;
243-
244- for ( const [ key , descriptor ] of Object . entries ( descriptors ) ) {
245- // Skip constructor and non-getter properties
246- if ( key === 'constructor' || typeof descriptor . get !== 'function' ) {
247- continue ;
239+ const configurationSections = packageJson ?. contributes ?. configuration ;
240+ if ( ! configurationSections || ! Array . isArray ( configurationSections ) ) {
241+ return JSON . stringify ( { error : 'No configuration found in package.json' } , null , 2 ) ;
242+ }
243+
244+ // Collect all setting keys from package.json, grouped by their section prefix
245+ const settingsBySection : Record < string , string [ ] > = { } ;
246+
247+ for ( const section of configurationSections ) {
248+ if ( section . properties ) {
249+ for ( const fullKey of Object . keys ( section . properties ) ) {
250+ // Split the full key (e.g., "dotnet.server.path") into section and rest
251+ const dotIndex = fullKey . indexOf ( '.' ) ;
252+ if ( dotIndex > 0 ) {
253+ const sectionName = fullKey . substring ( 0 , dotIndex ) ;
254+ if ( ! settingsBySection [ sectionName ] ) {
255+ settingsBySection [ sectionName ] = [ ] ;
256+ }
257+ settingsBySection [ sectionName ] . push ( fullKey ) ;
258+ }
259+ }
260+ }
261+ }
262+
263+ // Get the current value for each setting
264+ const result : Record < string , Record < string , unknown > > = { } ;
265+
266+ for ( const [ sectionName , settingKeys ] of Object . entries ( settingsBySection ) ) {
267+ result [ sectionName ] = { } ;
268+ const config = vscode . workspace . getConfiguration ( ) ;
269+
270+ for ( const fullKey of settingKeys ) {
271+ // Get the setting key without the section prefix for the result
272+ const keyWithoutSection = fullKey . substring ( sectionName . length + 1 ) ;
273+ result [ sectionName ] [ keyWithoutSection ] = config . get ( fullKey ) ;
248274 }
249- result [ key ] = ( options as Record < string , unknown > ) [ key ] ;
250275 }
251276
252- return result ;
277+ return JSON . stringify ( result , null , 2 ) ;
253278}
254279
255280/**
0 commit comments