99 JSONExt ,
1010 ReadonlyPartialJSONObject ,
1111 ReadonlyJSONObject ,
12+ PartialJSONObject ,
1213 PromiseDelegate
1314} from '@lumino/coreutils' ;
1415import { Signal , ISignal } from '@lumino/signaling' ;
@@ -74,6 +75,40 @@ function getDefaults(
7475 return defaults ;
7576}
7677
78+ /**
79+ * Get a mutable property matching a dotted key.
80+ *
81+ * Most LSP server schema properties are flattened using dotted convention,
82+ * e.g. a key for {pylsp: {plugins: {flake8: {enabled: true}}}}` is stored
83+ * as `pylsp.plugins.flake8.enabled`. However, some servers (e.g. pyright)
84+ * define specific properties as only partially doted, for example
85+ * `python.analysis.diagnosticSeverityOverrides` is an object with
86+ * properties like `reportGeneralTypeIssues` or `reportPropertyTypeMismatch`.
87+ * Only one level of nesting (on the finale level) is supported.
88+ */
89+ function findSchemaProperty (
90+ properties : PartialJSONObject ,
91+ key : string
92+ ) : PartialJSONObject | null {
93+ if ( properties . hasOwnProperty ( key ) ) {
94+ return properties [ key ] as PartialJSONObject ;
95+ }
96+ const parts = key . split ( '.' ) ;
97+ const prefix = parts . slice ( 0 , - 1 ) . join ( '.' ) ;
98+ const suffix = parts [ parts . length - 1 ] ;
99+ if ( properties . hasOwnProperty ( prefix ) ) {
100+ const parent = properties [ prefix ] as PartialJSONObject ;
101+ if ( parent . type !== 'object' ) {
102+ return null ;
103+ }
104+ const parentProperties = parent . properties as PartialJSONObject ;
105+ if ( parentProperties . hasOwnProperty ( suffix ) ) {
106+ return parentProperties [ suffix ] as PartialJSONObject ;
107+ }
108+ }
109+ return null ;
110+ }
111+
77112/**
78113 * Schema and user data that for validation
79114 */
@@ -315,25 +350,24 @@ export class SettingsSchemaManager {
315350 }
316351 }
317352
318- // add default overrides from spec
353+ // add default overrides from server-side spec (such as defined in `jupyter_server_config.py`)
319354 const workspaceConfigurationDefaults =
320355 serverSpec . workspace_configuration as Record < string , any > | undefined ;
321356 if ( workspaceConfigurationDefaults ) {
322357 for ( const [ key , value ] of Object . entries (
323358 workspaceConfigurationDefaults
324359 ) ) {
325- if ( ! configSchema . properties . hasOwnProperty ( key ) ) {
360+ const property = findSchemaProperty ( configSchema . properties , key ) ;
361+ if ( ! property ) {
326362 this . console . warn (
327- '`workspace_configuration` includes an override for key not in schema' ,
328- key ,
329- serverKey
363+ `"workspace_configuration" includes an override for "${ key } " key which was not found in ${ serverKey } schema'`
330364 ) ;
331365 continue ;
332366 }
333- configSchema . properties [ key ] . default = value ;
367+ property . default = value ;
334368 }
335369 }
336- // add server-specific default overrides from overrides.json (and pre-defined in schema)
370+ // add server-specific default overrides from ` overrides.json` (and pre-defined in schema)
337371 const serverDefaultsOverrides =
338372 defaultsOverrides && defaultsOverrides . hasOwnProperty ( serverKey )
339373 ? defaultsOverrides [ serverKey ]
@@ -342,15 +376,14 @@ export class SettingsSchemaManager {
342376 for ( const [ key , value ] of Object . entries (
343377 serverDefaultsOverrides . serverSettings
344378 ) ) {
345- if ( ! configSchema . properties . hasOwnProperty ( key ) ) {
379+ const property = findSchemaProperty ( configSchema . properties , key ) ;
380+ if ( ! property ) {
346381 this . console . warn (
347- '`overrides.json` includes an override for key not in schema' ,
348- key ,
349- serverKey
382+ `"overrides.json" includes an override for "${ key } " key which was not found in ${ serverKey } schema`
350383 ) ;
351384 continue ;
352385 }
353- configSchema . properties [ key ] . default = value ;
386+ property . default = value as any ;
354387 }
355388 }
356389
0 commit comments