configurations.ts ×15

Frontier kind: Code frontier

unlabeled · c_4b5020976c87

22 tests · 15384 LOC · 71 files · introduces 0 tests · 128 LOC · 3 files

Introduces — evidence that enters the hierarchy at this concept

Code
25 ranges128 lines · 3 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2368 ranges15384 lines · 71 files · Browse complete extent
All tests (intent)
22 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

3 files ranked by introduced lines: 128 introduced LOC across 25 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/configuration/common/configurations.ts 93 introduced LOC · 15 ranges

Open complete file

111
112 constructor(
113 > private readonly defaultConfiguration: DefaultConfiguration, configurations.ts
114 > @IPolicyService private readonly policyService: IPolicyService,
115 > @ILogService private readonly logService: ILogService
116 > ) {
117 > super();
118 > this._configurationModel = ConfigurationModel.createEmptyModel(this.logService);
119 > this.configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
120 > }
121
122 async initialize(): Promise<ConfigurationModel> {
123 > this.logService.trace('PolicyConfiguration#initialize'); configurations.ts
124 >
125 > this.update(await this.updatePolicyDefinitions(this.defaultConfiguration.configurationModel.keys), false);
126 > this.update(await this.updatePolicyDefinitions(Object.keys(this.configurationRegistry.getExcludedConfigurationProperties())), false);
127 > this._register(this.policyService.onDidChange(policyNames => this.onDidChangePolicies(policyNames)));
128 > this._register(this.defaultConfiguration.onDidChangeConfiguration(async ({ properties }) => this.update(await this.updatePolicyDefinitions(properties), true)));
129 > return this._configurationModel;
130 > }
131
132 private toPolicyDefinitionType(configType: unknown, policyName: PolicyName): 'string' | 'number' | 'boolean' | undefined {
133 > // `configType` may be a single type or a union (e.g. `['array', 'null']`). configurations.ts
134 > // Normalize to an array and keep only the types we can represent as policies.
135 > const configTypes = Array.isArray(configType) ? configType : [configType];
136 > const supportedTypes = configTypes.filter(type => type === 'string' || type === 'number' || type === 'array' || type === 'object' || type === 'boolean');
137 > if (supportedTypes.length === 0) {
138 this.logService.warn(`PolicyConfiguration#updatePolicyDefinitions - policy '${policyName}' has unsupported type '${configType}'`);
139 return undefined;
140 }
141 > return supportedTypes.includes('number') ? 'number' : supportedTypes.includes('boolean') ? 'boolean' : 'string'; configurations.ts
142 > }
143
144 private async updatePolicyDefinitions(properties: string[]): Promise<string[]> {
145 > this.logService.trace('PolicyConfiguration#updatePolicyDefinitions', properties); configurations.ts
146 > const keys: string[] = [];
147 > const policyNames = new Set<PolicyName>();
148 > const configurationProperties = this.configurationRegistry.getConfigurationProperties();
149 > const excludedConfigurationProperties = this.configurationRegistry.getExcludedConfigurationProperties();
150 >
151 > for (const key of properties) {
152 > const config = configurationProperties[key] ?? excludedConfigurationProperties[key];
153 > if (!config) {
154 keys.push(key); // deregistered — update() will clear this key's applied policy value
155 const removedPolicyName = this._policyNameByKey.get(key);
160 continue;
161 }
162 > const policyName = config.policy?.name ?? config.policyReference?.name; configurations.ts
163 > if (policyName) {
164 > keys.push(key);
165 > policyNames.add(policyName);
166 > this._policyNameByKey.set(key, policyName);
167 > }
168 > }
169 >
170 > const changedDefinitions: IStringDictionary<PolicyDefinition> = {};
171 > for (const policyName of policyNames) {
172 > const definition = this.resolvePolicyDefinition(policyName);
173 > if (definition && !this.isSamePolicyDefinition(this._submittedPolicyDefinitions.get(policyName), definition)) {
174 > this._submittedPolicyDefinitions.set(policyName, definition);
175 > changedDefinitions[policyName] = definition;
176 > }
177 > }
178 >
179 > if (!isEmptyObject(changedDefinitions)) {
180 > await this.policyService.updatePolicyDefinitions(changedDefinitions);
181 > }
182 >
183 > return keys;
184 > }
185
186 private isSamePolicyDefinition(a: PolicyDefinition | undefined, b: PolicyDefinition): boolean {
187 > return !!a && a.type === b.type && a.value === b.value && a.managedSettings === b.managedSettings && a.restrictedValue === b.restrictedValue; configurations.ts
188 > }
189
190 /** Resolve the authoritative definition: owner wins; references provide a bare type fallback. */
191 private resolvePolicyDefinition(policyName: PolicyName): PolicyDefinition | undefined {
192 > const configurationProperties = this.configurationRegistry.getConfigurationProperties(); configurations.ts
193 > const excludedConfigurationProperties = this.configurationRegistry.getExcludedConfigurationProperties();
194 >
195 > const ownerKey = this.configurationRegistry.getPolicyConfigurations().get(policyName);
196 > if (ownerKey !== undefined) {
197 > const config = configurationProperties[ownerKey] ?? excludedConfigurationProperties[ownerKey];
198 > if (config?.policy) {
199 > const type = this.toPolicyDefinitionType(config.type, policyName);
200 > const { value, managedSettings, restrictedValue } = config.policy;
201 > return type ? { type, value, managedSettings, restrictedValue } : undefined;
202 > }
203 > }
204
205 const referenceKeys = this.configurationRegistry.getPolicyReferenceConfigurations().get(policyName);
206 > for (const referenceKey of referenceKeys ?? []) { configurations.ts
207 const config = configurationProperties[referenceKey] ?? excludedConfigurationProperties[referenceKey];
208 if (config?.policyReference) {
213
214 return undefined;
216
217 private onDidChangePolicies(policyNames: readonly PolicyName[]): void {
234
235 private update(keys: string[], trigger: boolean): void {
236 > this.logService.trace('PolicyConfiguration#update', keys); configurations.ts
237 > const configurationProperties = this.configurationRegistry.getConfigurationProperties();
238 > const excludedConfigurationProperties = this.configurationRegistry.getExcludedConfigurationProperties();
239 > const changed: [string, unknown][] = [];
240 > const wasEmpty = this._configurationModel.isEmpty();
241 >
242 > for (const key of keys) {
243 > const property = configurationProperties[key] ?? excludedConfigurationProperties[key];
244 > const policyName = property?.policy?.name ?? property?.policyReference?.name;
245 > if (policyName) {
246 > let policyValue: PolicyValue | ParsedType | undefined = this.policyService.getPolicyValue(policyName);
247 > // `property.type` may be a single type or a union (e.g. `['array', 'null']`).
248 > // A string policy value carries a JSON payload that must be parsed unless the
249 > // setting itself is (or can be) a plain string.
250 > const acceptsStringType = Array.isArray(property.type) ? property.type.includes('string') : property.type === 'string';
251 > if (isString(policyValue) && !acceptsStringType) {
252 try {
253 policyValue = this.parse(policyValue);
257 }
258 }
259 > if (wasEmpty ? policyValue !== undefined : !equals(this._configurationModel.getValue(key), policyValue)) { configurations.ts
260 changed.push([key, policyValue]);
261 }
262 > } else { configurations.ts
263 if (this._configurationModel.getValue(key) !== undefined) {
264 changed.push([key, undefined]);
265 }
266 }
268 >
269 > if (changed.length) {
270 this.logService.trace('PolicyConfiguration#changed', changed);
271 const old = this._configurationModel;
285 }
286 }
288
289 private parse(content: string): ParsedType {
src/vs/platform/policy/common/filePolicyService.ts 33 introduced LOC · 9 ranges

Open complete file

14 import { AbstractPolicyService, IPolicyService, PolicyValue } from './policy.js';
15
16 > function keysDiff<T>(a: Map<string, T>, b: Map<string, T>): string[] { filePolicyService.ts
17 > const result: string[] = [];
18 >
19 > for (const key of new Set(Iterable.concat(a.keys(), b.keys()))) {
20 if (a.get(key) !== b.get(key)) {
21 result.push(key);
22 }
23 }
25 > return result;
26 > }
27
28 export class FilePolicyService extends AbstractPolicyService implements IPolicyService {
31
32 constructor(
33 > private readonly file: URI, filePolicyService.ts
34 > @IFileService private readonly fileService: IFileService,
35 > @ILogService private readonly logService: ILogService
36 > ) {
37 > super();
38 >
39 > const onDidChangePolicyFile = Event.filter(fileService.onDidFilesChange, e => e.affects(file));
40 > this._register(fileService.watch(file));
41 > this._register(onDidChangePolicyFile(() => this.throttledDelayer.trigger(() => this.refresh())));
42 > }
43
44 protected async _updatePolicyDefinitions(): Promise<void> {
45 > await this.refresh(); filePolicyService.ts
46 > }
47
48 private async read(): Promise<Map<PolicyName, PolicyValue>> {
49 > const policies = new Map<PolicyName, PolicyValue>(); filePolicyService.ts
50 >
51 > try {
52 > const content = await this.fileService.readFile(this.file);
53 const raw = JSON.parse(content.value.toString());
54
62 }
63 }
64 > } catch (error) { filePolicyService.ts
65 if ((<FileOperationError>error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND) {
66 this.logService.error(`[FilePolicyService] Failed to read policies`, error);
67 }
68 }
70 > return policies;
71 > }
72
73 private async refresh(): Promise<void> {
74 > const policies = await this.read(); filePolicyService.ts
75 > const diff = keysDiff(this.policies, policies);
76 > this.policies = policies;
77 >
78 > if (diff.length > 0) {
79 this._onDidChange.fire(diff);
80 }
82 }
src/vs/platform/policy/common/policy.ts 2 introduced LOC · 1 range

Open complete file

80
81 getPolicyValue(name: PolicyName): PolicyValue | undefined {
82 > return this.policies.get(name); policy.ts
83 > }
84
85 serialize(): IStringDictionary<{ definition: PolicyDefinition; value: PolicyValue }> {