vscode-json-languageservice 5.7.2 → 6.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/lib/esm/jsonContributions.d.ts +1 -1
  3. package/lib/esm/jsonLanguageService.d.ts +2 -2
  4. package/lib/esm/jsonLanguageService.js +13 -13
  5. package/lib/esm/jsonLanguageTypes.d.ts +10 -2
  6. package/lib/esm/jsonSchema.d.ts +71 -2
  7. package/lib/esm/parser/jsonParser.js +224 -93
  8. package/lib/esm/services/configuration.js +2 -2
  9. package/lib/esm/services/jsonCompletion.js +5 -5
  10. package/lib/esm/services/jsonDocumentSymbols.js +4 -4
  11. package/lib/esm/services/jsonFolding.js +1 -1
  12. package/lib/esm/services/jsonHover.js +2 -2
  13. package/lib/esm/services/jsonLinks.js +94 -3
  14. package/lib/esm/services/jsonSchemaService.js +639 -100
  15. package/lib/esm/services/jsonSelectionRanges.js +1 -1
  16. package/lib/esm/services/jsonValidation.js +4 -4
  17. package/lib/esm/services/schemas/draft-2019-09-flat.d.ts +1 -1
  18. package/lib/esm/services/schemas/draft-2020-12-flat.d.ts +1 -1
  19. package/lib/esm/services/vocabularies.js +139 -0
  20. package/lib/esm/utils/format.js +1 -1
  21. package/lib/esm/utils/sort.js +3 -3
  22. package/package.json +23 -20
  23. package/lib/umd/jsonContributions.d.ts +0 -21
  24. package/lib/umd/jsonContributions.js +0 -12
  25. package/lib/umd/jsonLanguageService.d.ts +0 -30
  26. package/lib/umd/jsonLanguageService.js +0 -79
  27. package/lib/umd/jsonLanguageTypes.d.ts +0 -305
  28. package/lib/umd/jsonLanguageTypes.js +0 -109
  29. package/lib/umd/jsonSchema.d.ts +0 -92
  30. package/lib/umd/jsonSchema.js +0 -12
  31. package/lib/umd/parser/jsonParser.js +0 -1365
  32. package/lib/umd/services/configuration.js +0 -536
  33. package/lib/umd/services/jsonCompletion.js +0 -982
  34. package/lib/umd/services/jsonDocumentSymbols.js +0 -285
  35. package/lib/umd/services/jsonFolding.js +0 -133
  36. package/lib/umd/services/jsonHover.js +0 -125
  37. package/lib/umd/services/jsonLinks.js +0 -85
  38. package/lib/umd/services/jsonSchemaService.js +0 -631
  39. package/lib/umd/services/jsonSelectionRanges.js +0 -74
  40. package/lib/umd/services/jsonValidation.js +0 -165
  41. package/lib/umd/services/schemas/draft-2019-09-flat.d.ts +0 -278
  42. package/lib/umd/services/schemas/draft-2019-09-flat.js +0 -314
  43. package/lib/umd/services/schemas/draft-2020-12-flat.d.ts +0 -276
  44. package/lib/umd/services/schemas/draft-2020-12-flat.js +0 -307
  45. package/lib/umd/utils/colors.js +0 -83
  46. package/lib/umd/utils/format.js +0 -33
  47. package/lib/umd/utils/glob.js +0 -137
  48. package/lib/umd/utils/json.js +0 -55
  49. package/lib/umd/utils/objects.js +0 -86
  50. package/lib/umd/utils/propertyTree.js +0 -90
  51. package/lib/umd/utils/sort.js +0 -384
  52. package/lib/umd/utils/strings.js +0 -97
@@ -1,631 +0,0 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the MIT License. See License.txt in the project root for license information.
4
- *--------------------------------------------------------------------------------------------*/
5
- (function (factory) {
6
- if (typeof module === "object" && typeof module.exports === "object") {
7
- var v = factory(require, exports);
8
- if (v !== undefined) module.exports = v;
9
- }
10
- else if (typeof define === "function" && define.amd) {
11
- define(["require", "exports", "jsonc-parser", "vscode-uri", "../utils/strings", "../parser/jsonParser", "../jsonLanguageTypes", "@vscode/l10n", "../utils/glob", "../utils/objects", "vscode-languageserver-types"], factory);
12
- }
13
- })(function (require, exports) {
14
- "use strict";
15
- Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.JSONSchemaService = exports.ResolvedSchema = exports.UnresolvedSchema = void 0;
17
- const Json = require("jsonc-parser");
18
- const vscode_uri_1 = require("vscode-uri");
19
- const Strings = require("../utils/strings");
20
- const jsonParser_1 = require("../parser/jsonParser");
21
- const jsonLanguageTypes_1 = require("../jsonLanguageTypes");
22
- const l10n = require("@vscode/l10n");
23
- const glob_1 = require("../utils/glob");
24
- const objects_1 = require("../utils/objects");
25
- const vscode_languageserver_types_1 = require("vscode-languageserver-types");
26
- const BANG = '!';
27
- const PATH_SEP = '/';
28
- class FilePatternAssociation {
29
- constructor(pattern, folderUri, uris) {
30
- this.folderUri = folderUri;
31
- this.uris = uris;
32
- this.globWrappers = [];
33
- try {
34
- for (let patternString of pattern) {
35
- const include = patternString[0] !== BANG;
36
- if (!include) {
37
- patternString = patternString.substring(1);
38
- }
39
- if (patternString.length > 0) {
40
- if (patternString[0] === PATH_SEP) {
41
- patternString = patternString.substring(1);
42
- }
43
- this.globWrappers.push({
44
- regexp: (0, glob_1.createRegex)('**/' + patternString, { extended: true, globstar: true }),
45
- include: include,
46
- });
47
- }
48
- }
49
- ;
50
- if (folderUri) {
51
- folderUri = normalizeResourceForMatching(folderUri);
52
- if (!folderUri.endsWith('/')) {
53
- folderUri = folderUri + '/';
54
- }
55
- this.folderUri = folderUri;
56
- }
57
- }
58
- catch (e) {
59
- this.globWrappers.length = 0;
60
- this.uris = [];
61
- }
62
- }
63
- matchesPattern(fileName) {
64
- if (this.folderUri && !fileName.startsWith(this.folderUri)) {
65
- return false;
66
- }
67
- let match = false;
68
- for (const { regexp, include } of this.globWrappers) {
69
- if (regexp.test(fileName)) {
70
- match = include;
71
- }
72
- }
73
- return match;
74
- }
75
- getURIs() {
76
- return this.uris;
77
- }
78
- }
79
- class SchemaHandle {
80
- constructor(service, uri, unresolvedSchemaContent) {
81
- this.service = service;
82
- this.uri = uri;
83
- this.dependencies = new Set();
84
- this.anchors = undefined;
85
- if (unresolvedSchemaContent) {
86
- this.unresolvedSchema = this.service.promise.resolve(new UnresolvedSchema(unresolvedSchemaContent));
87
- }
88
- }
89
- getUnresolvedSchema() {
90
- if (!this.unresolvedSchema) {
91
- this.unresolvedSchema = this.service.loadSchema(this.uri);
92
- }
93
- return this.unresolvedSchema;
94
- }
95
- getResolvedSchema() {
96
- if (!this.resolvedSchema) {
97
- this.resolvedSchema = this.getUnresolvedSchema().then(unresolved => {
98
- return this.service.resolveSchemaContent(unresolved, this);
99
- });
100
- }
101
- return this.resolvedSchema;
102
- }
103
- clearSchema() {
104
- const hasChanges = !!this.unresolvedSchema;
105
- this.resolvedSchema = undefined;
106
- this.unresolvedSchema = undefined;
107
- this.dependencies.clear();
108
- this.anchors = undefined;
109
- return hasChanges;
110
- }
111
- }
112
- class UnresolvedSchema {
113
- constructor(schema, errors = []) {
114
- this.schema = schema;
115
- this.errors = errors;
116
- }
117
- }
118
- exports.UnresolvedSchema = UnresolvedSchema;
119
- function toDiagnostic(message, code, relatedURL) {
120
- const relatedInformation = relatedURL ? [{
121
- location: { uri: relatedURL, range: vscode_languageserver_types_1.Range.create(0, 0, 0, 0) },
122
- message
123
- }] : undefined;
124
- return { message, code, relatedInformation };
125
- }
126
- class ResolvedSchema {
127
- constructor(schema, errors = [], warnings = [], schemaDraft) {
128
- this.schema = schema;
129
- this.errors = errors;
130
- this.warnings = warnings;
131
- this.schemaDraft = schemaDraft;
132
- }
133
- getSection(path) {
134
- const schemaRef = this.getSectionRecursive(path, this.schema);
135
- if (schemaRef) {
136
- return (0, jsonParser_1.asSchema)(schemaRef);
137
- }
138
- return undefined;
139
- }
140
- getSectionRecursive(path, schema) {
141
- if (!schema || typeof schema === 'boolean' || path.length === 0) {
142
- return schema;
143
- }
144
- const next = path.shift();
145
- if (schema.properties && typeof schema.properties[next]) {
146
- return this.getSectionRecursive(path, schema.properties[next]);
147
- }
148
- else if (schema.patternProperties) {
149
- for (const pattern of Object.keys(schema.patternProperties)) {
150
- const regex = Strings.extendedRegExp(pattern);
151
- if (regex?.test(next)) {
152
- return this.getSectionRecursive(path, schema.patternProperties[pattern]);
153
- }
154
- }
155
- }
156
- else if (typeof schema.additionalProperties === 'object') {
157
- return this.getSectionRecursive(path, schema.additionalProperties);
158
- }
159
- else if (next.match('[0-9]+')) {
160
- if (Array.isArray(schema.items)) {
161
- const index = parseInt(next, 10);
162
- if (!isNaN(index) && schema.items[index]) {
163
- return this.getSectionRecursive(path, schema.items[index]);
164
- }
165
- }
166
- else if (schema.items) {
167
- return this.getSectionRecursive(path, schema.items);
168
- }
169
- }
170
- return undefined;
171
- }
172
- }
173
- exports.ResolvedSchema = ResolvedSchema;
174
- class JSONSchemaService {
175
- constructor(requestService, contextService, promiseConstructor) {
176
- this.contextService = contextService;
177
- this.requestService = requestService;
178
- this.promiseConstructor = promiseConstructor || Promise;
179
- this.callOnDispose = [];
180
- this.contributionSchemas = {};
181
- this.contributionAssociations = [];
182
- this.schemasById = {};
183
- this.filePatternAssociations = [];
184
- this.registeredSchemasIds = {};
185
- }
186
- getRegisteredSchemaIds(filter) {
187
- return Object.keys(this.registeredSchemasIds).filter(id => {
188
- const scheme = vscode_uri_1.URI.parse(id).scheme;
189
- return scheme !== 'schemaservice' && (!filter || filter(scheme));
190
- });
191
- }
192
- get promise() {
193
- return this.promiseConstructor;
194
- }
195
- dispose() {
196
- while (this.callOnDispose.length > 0) {
197
- this.callOnDispose.pop()();
198
- }
199
- }
200
- onResourceChange(uri) {
201
- // always clear this local cache when a resource changes
202
- this.cachedSchemaForResource = undefined;
203
- let hasChanges = false;
204
- uri = (0, jsonParser_1.normalizeId)(uri);
205
- const toWalk = [uri];
206
- const all = Object.keys(this.schemasById).map(key => this.schemasById[key]);
207
- while (toWalk.length) {
208
- const curr = toWalk.pop();
209
- for (let i = 0; i < all.length; i++) {
210
- const handle = all[i];
211
- if (handle && (handle.uri === curr || handle.dependencies.has(curr))) {
212
- if (handle.uri !== curr) {
213
- toWalk.push(handle.uri);
214
- }
215
- if (handle.clearSchema()) {
216
- hasChanges = true;
217
- }
218
- all[i] = undefined;
219
- }
220
- }
221
- }
222
- return hasChanges;
223
- }
224
- setSchemaContributions(schemaContributions) {
225
- if (schemaContributions.schemas) {
226
- const schemas = schemaContributions.schemas;
227
- for (const id in schemas) {
228
- const normalizedId = (0, jsonParser_1.normalizeId)(id);
229
- this.contributionSchemas[normalizedId] = this.addSchemaHandle(normalizedId, schemas[id]);
230
- }
231
- }
232
- if (Array.isArray(schemaContributions.schemaAssociations)) {
233
- const schemaAssociations = schemaContributions.schemaAssociations;
234
- for (let schemaAssociation of schemaAssociations) {
235
- const uris = schemaAssociation.uris.map(jsonParser_1.normalizeId);
236
- const association = this.addFilePatternAssociation(schemaAssociation.pattern, schemaAssociation.folderUri, uris);
237
- this.contributionAssociations.push(association);
238
- }
239
- }
240
- }
241
- addSchemaHandle(id, unresolvedSchemaContent) {
242
- const schemaHandle = new SchemaHandle(this, id, unresolvedSchemaContent);
243
- this.schemasById[id] = schemaHandle;
244
- return schemaHandle;
245
- }
246
- getOrAddSchemaHandle(id, unresolvedSchemaContent) {
247
- return this.schemasById[id] || this.addSchemaHandle(id, unresolvedSchemaContent);
248
- }
249
- addFilePatternAssociation(pattern, folderUri, uris) {
250
- const fpa = new FilePatternAssociation(pattern, folderUri, uris);
251
- this.filePatternAssociations.push(fpa);
252
- return fpa;
253
- }
254
- registerExternalSchema(config) {
255
- const id = (0, jsonParser_1.normalizeId)(config.uri);
256
- this.registeredSchemasIds[id] = true;
257
- this.cachedSchemaForResource = undefined;
258
- if (config.fileMatch && config.fileMatch.length) {
259
- this.addFilePatternAssociation(config.fileMatch, config.folderUri, [id]);
260
- }
261
- return config.schema ? this.addSchemaHandle(id, config.schema) : this.getOrAddSchemaHandle(id);
262
- }
263
- clearExternalSchemas() {
264
- this.schemasById = {};
265
- this.filePatternAssociations = [];
266
- this.registeredSchemasIds = {};
267
- this.cachedSchemaForResource = undefined;
268
- for (const id in this.contributionSchemas) {
269
- this.schemasById[id] = this.contributionSchemas[id];
270
- this.registeredSchemasIds[id] = true;
271
- }
272
- for (const contributionAssociation of this.contributionAssociations) {
273
- this.filePatternAssociations.push(contributionAssociation);
274
- }
275
- }
276
- getResolvedSchema(schemaId) {
277
- const id = (0, jsonParser_1.normalizeId)(schemaId);
278
- const schemaHandle = this.schemasById[id];
279
- if (schemaHandle) {
280
- return schemaHandle.getResolvedSchema();
281
- }
282
- return this.promise.resolve(undefined);
283
- }
284
- loadSchema(url) {
285
- if (!this.requestService) {
286
- const errorMessage = l10n.t('Unable to load schema from \'{0}\'. No schema request service available', toDisplayString(url));
287
- return this.promise.resolve(new UnresolvedSchema({}, [toDiagnostic(errorMessage, jsonLanguageTypes_1.ErrorCode.SchemaResolveError, url)]));
288
- }
289
- return this.requestService(url).then(content => {
290
- if (!content) {
291
- const errorMessage = l10n.t('Unable to load schema from \'{0}\': No content.', toDisplayString(url));
292
- return new UnresolvedSchema({}, [toDiagnostic(errorMessage, jsonLanguageTypes_1.ErrorCode.SchemaResolveError, url)]);
293
- }
294
- const errors = [];
295
- if (content.charCodeAt(0) === 65279) {
296
- errors.push(toDiagnostic(l10n.t('Problem reading content from \'{0}\': UTF-8 with BOM detected, only UTF 8 is allowed.', toDisplayString(url)), jsonLanguageTypes_1.ErrorCode.SchemaResolveError, url));
297
- content = content.trimStart();
298
- }
299
- let schemaContent = {};
300
- const jsonErrors = [];
301
- schemaContent = Json.parse(content, jsonErrors);
302
- if (jsonErrors.length) {
303
- errors.push(toDiagnostic(l10n.t('Unable to parse content from \'{0}\': Parse error at offset {1}.', toDisplayString(url), jsonErrors[0].offset), jsonLanguageTypes_1.ErrorCode.SchemaResolveError, url));
304
- }
305
- return new UnresolvedSchema(schemaContent, errors);
306
- }, (error) => {
307
- let { message, code } = error;
308
- if (typeof message !== 'string') {
309
- let errorMessage = error.toString();
310
- const errorSplit = error.toString().split('Error: ');
311
- if (errorSplit.length > 1) {
312
- // more concise error message, URL and context are attached by caller anyways
313
- errorMessage = errorSplit[1];
314
- }
315
- if (Strings.endsWith(errorMessage, '.')) {
316
- errorMessage = errorMessage.substr(0, errorMessage.length - 1);
317
- }
318
- message = errorMessage;
319
- }
320
- let errorCode = jsonLanguageTypes_1.ErrorCode.SchemaResolveError;
321
- if (typeof code === 'number' && code < 0x10000) {
322
- errorCode += code;
323
- }
324
- const errorMessage = l10n.t('Unable to load schema from \'{0}\': {1}.', toDisplayString(url), message);
325
- return new UnresolvedSchema({}, [toDiagnostic(errorMessage, errorCode, url)]);
326
- });
327
- }
328
- resolveSchemaContent(schemaToResolve, handle) {
329
- const resolveErrors = schemaToResolve.errors.slice(0);
330
- const schema = schemaToResolve.schema;
331
- const schemaDraft = schema.$schema ? (0, jsonParser_1.getSchemaDraftFromId)(schema.$schema) : undefined;
332
- if (schemaDraft === jsonLanguageTypes_1.SchemaDraft.v3) {
333
- return this.promise.resolve(new ResolvedSchema({}, [toDiagnostic(l10n.t("Draft-03 schemas are not supported."), jsonLanguageTypes_1.ErrorCode.SchemaUnsupportedFeature)], [], schemaDraft));
334
- }
335
- let usesUnsupportedFeatures = new Set();
336
- const contextService = this.contextService;
337
- const findSectionByJSONPointer = (schema, path) => {
338
- path = decodeURIComponent(path);
339
- let current = schema;
340
- if (path[0] === '/') {
341
- path = path.substring(1);
342
- }
343
- path.split('/').some((part) => {
344
- part = part.replace(/~1/g, '/').replace(/~0/g, '~');
345
- current = current[part];
346
- return !current;
347
- });
348
- return current;
349
- };
350
- const findSchemaById = (schema, handle, id) => {
351
- if (!handle.anchors) {
352
- handle.anchors = collectAnchors(schema);
353
- }
354
- return handle.anchors.get(id);
355
- };
356
- const merge = (target, section) => {
357
- for (const key in section) {
358
- if (section.hasOwnProperty(key) && key !== 'id' && key !== '$id') {
359
- target[key] = section[key];
360
- }
361
- }
362
- };
363
- const mergeRef = (target, sourceRoot, sourceHandle, refSegment) => {
364
- let section;
365
- if (refSegment === undefined || refSegment.length === 0) {
366
- section = sourceRoot;
367
- }
368
- else if (refSegment.charAt(0) === '/') {
369
- // A $ref to a JSON Pointer (i.e #/definitions/foo)
370
- section = findSectionByJSONPointer(sourceRoot, refSegment);
371
- }
372
- else {
373
- // A $ref to a sub-schema with an $id (i.e #hello)
374
- section = findSchemaById(sourceRoot, sourceHandle, refSegment);
375
- }
376
- if (section) {
377
- merge(target, section);
378
- }
379
- else {
380
- const message = l10n.t('$ref \'{0}\' in \'{1}\' can not be resolved.', refSegment || '', sourceHandle.uri);
381
- resolveErrors.push(toDiagnostic(message, jsonLanguageTypes_1.ErrorCode.SchemaResolveError));
382
- }
383
- };
384
- const resolveExternalLink = (node, uri, refSegment, parentHandle) => {
385
- if (contextService && !/^[A-Za-z][A-Za-z0-9+\-.+]*:\/.*/.test(uri)) {
386
- uri = contextService.resolveRelativePath(uri, parentHandle.uri);
387
- }
388
- uri = (0, jsonParser_1.normalizeId)(uri);
389
- const referencedHandle = this.getOrAddSchemaHandle(uri);
390
- return referencedHandle.getUnresolvedSchema().then(unresolvedSchema => {
391
- parentHandle.dependencies.add(uri);
392
- if (unresolvedSchema.errors.length) {
393
- const error = unresolvedSchema.errors[0];
394
- const loc = refSegment ? uri + '#' + refSegment : uri;
395
- const errorMessage = refSegment ? l10n.t('Problems loading reference \'{0}\': {1}', refSegment, error.message) : error.message;
396
- resolveErrors.push(toDiagnostic(errorMessage, error.code, uri));
397
- }
398
- mergeRef(node, unresolvedSchema.schema, referencedHandle, refSegment);
399
- return resolveRefs(node, unresolvedSchema.schema, referencedHandle);
400
- });
401
- };
402
- const resolveRefs = (node, parentSchema, parentHandle) => {
403
- const openPromises = [];
404
- this.traverseNodes(node, next => {
405
- const seenRefs = new Set();
406
- while (next.$ref) {
407
- const ref = next.$ref;
408
- const segments = ref.split('#', 2);
409
- delete next.$ref;
410
- if (segments[0].length > 0) {
411
- // This is a reference to an external schema
412
- openPromises.push(resolveExternalLink(next, segments[0], segments[1], parentHandle));
413
- return;
414
- }
415
- else {
416
- // This is a reference inside the current schema
417
- if (!seenRefs.has(ref)) {
418
- const id = segments[1];
419
- mergeRef(next, parentSchema, parentHandle, id);
420
- seenRefs.add(ref);
421
- }
422
- }
423
- }
424
- if (next.$recursiveRef) {
425
- usesUnsupportedFeatures.add('$recursiveRef');
426
- }
427
- if (next.$dynamicRef) {
428
- usesUnsupportedFeatures.add('$dynamicRef');
429
- }
430
- });
431
- return this.promise.all(openPromises);
432
- };
433
- const collectAnchors = (root) => {
434
- const result = new Map();
435
- this.traverseNodes(root, next => {
436
- const id = next.$id || next.id;
437
- const anchor = (0, objects_1.isString)(id) && id.charAt(0) === '#' ? id.substring(1) : next.$anchor;
438
- if (anchor) {
439
- if (result.has(anchor)) {
440
- resolveErrors.push(toDiagnostic(l10n.t('Duplicate anchor declaration: \'{0}\'', anchor), jsonLanguageTypes_1.ErrorCode.SchemaResolveError));
441
- }
442
- else {
443
- result.set(anchor, next);
444
- }
445
- }
446
- if (next.$recursiveAnchor) {
447
- usesUnsupportedFeatures.add('$recursiveAnchor');
448
- }
449
- if (next.$dynamicAnchor) {
450
- usesUnsupportedFeatures.add('$dynamicAnchor');
451
- }
452
- });
453
- return result;
454
- };
455
- return resolveRefs(schema, schema, handle).then(_ => {
456
- let resolveWarnings = [];
457
- if (usesUnsupportedFeatures.size) {
458
- resolveWarnings.push(toDiagnostic(l10n.t('The schema uses meta-schema features ({0}) that are not yet supported by the validator.', Array.from(usesUnsupportedFeatures.keys()).join(', ')), jsonLanguageTypes_1.ErrorCode.SchemaUnsupportedFeature));
459
- }
460
- return new ResolvedSchema(schema, resolveErrors, resolveWarnings, schemaDraft);
461
- });
462
- }
463
- traverseNodes(root, handle) {
464
- if (!root || typeof root !== 'object') {
465
- return Promise.resolve(null);
466
- }
467
- const seen = new Set();
468
- const collectEntries = (...entries) => {
469
- for (const entry of entries) {
470
- if ((0, objects_1.isObject)(entry)) {
471
- toWalk.push(entry);
472
- }
473
- }
474
- };
475
- const collectMapEntries = (...maps) => {
476
- for (const map of maps) {
477
- if ((0, objects_1.isObject)(map)) {
478
- for (const k in map) {
479
- const key = k;
480
- const entry = map[key];
481
- if ((0, objects_1.isObject)(entry)) {
482
- toWalk.push(entry);
483
- }
484
- }
485
- }
486
- }
487
- };
488
- const collectArrayEntries = (...arrays) => {
489
- for (const array of arrays) {
490
- if (Array.isArray(array)) {
491
- for (const entry of array) {
492
- if ((0, objects_1.isObject)(entry)) {
493
- toWalk.push(entry);
494
- }
495
- }
496
- }
497
- }
498
- };
499
- const collectEntryOrArrayEntries = (items) => {
500
- if (Array.isArray(items)) {
501
- for (const entry of items) {
502
- if ((0, objects_1.isObject)(entry)) {
503
- toWalk.push(entry);
504
- }
505
- }
506
- }
507
- else if ((0, objects_1.isObject)(items)) {
508
- toWalk.push(items);
509
- }
510
- };
511
- const toWalk = [root];
512
- let next = toWalk.pop();
513
- while (next) {
514
- if (!seen.has(next)) {
515
- seen.add(next);
516
- handle(next);
517
- collectEntries(next.additionalItems, next.additionalProperties, next.not, next.contains, next.propertyNames, next.if, next.then, next.else, next.unevaluatedItems, next.unevaluatedProperties);
518
- collectMapEntries(next.definitions, next.$defs, next.properties, next.patternProperties, next.dependencies, next.dependentSchemas);
519
- collectArrayEntries(next.anyOf, next.allOf, next.oneOf, next.prefixItems);
520
- collectEntryOrArrayEntries(next.items);
521
- }
522
- next = toWalk.pop();
523
- }
524
- }
525
- ;
526
- getSchemaFromProperty(resource, document) {
527
- if (document.root?.type === 'object') {
528
- for (const p of document.root.properties) {
529
- if (p.keyNode.value === '$schema' && p.valueNode?.type === 'string') {
530
- let schemaId = p.valueNode.value;
531
- if (this.contextService && !/^\w[\w\d+.-]*:/.test(schemaId)) { // has scheme
532
- schemaId = this.contextService.resolveRelativePath(schemaId, resource);
533
- }
534
- return schemaId;
535
- }
536
- }
537
- }
538
- return undefined;
539
- }
540
- getAssociatedSchemas(resource) {
541
- const seen = Object.create(null);
542
- const schemas = [];
543
- const normalizedResource = normalizeResourceForMatching(resource);
544
- for (const entry of this.filePatternAssociations) {
545
- if (entry.matchesPattern(normalizedResource)) {
546
- for (const schemaId of entry.getURIs()) {
547
- if (!seen[schemaId]) {
548
- schemas.push(schemaId);
549
- seen[schemaId] = true;
550
- }
551
- }
552
- }
553
- }
554
- return schemas;
555
- }
556
- getSchemaURIsForResource(resource, document) {
557
- let schemeId = document && this.getSchemaFromProperty(resource, document);
558
- if (schemeId) {
559
- return [schemeId];
560
- }
561
- return this.getAssociatedSchemas(resource);
562
- }
563
- getSchemaForResource(resource, document) {
564
- if (document) {
565
- // first use $schema if present
566
- let schemeId = this.getSchemaFromProperty(resource, document);
567
- if (schemeId) {
568
- const id = (0, jsonParser_1.normalizeId)(schemeId);
569
- return this.getOrAddSchemaHandle(id).getResolvedSchema();
570
- }
571
- }
572
- if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
573
- return this.cachedSchemaForResource.resolvedSchema;
574
- }
575
- const schemas = this.getAssociatedSchemas(resource);
576
- const resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
577
- this.cachedSchemaForResource = { resource, resolvedSchema };
578
- return resolvedSchema;
579
- }
580
- createCombinedSchema(resource, schemaIds) {
581
- if (schemaIds.length === 1) {
582
- return this.getOrAddSchemaHandle(schemaIds[0]);
583
- }
584
- else {
585
- const combinedSchemaId = 'schemaservice://combinedSchema/' + encodeURIComponent(resource);
586
- const combinedSchema = {
587
- allOf: schemaIds.map(schemaId => ({ $ref: schemaId }))
588
- };
589
- return this.addSchemaHandle(combinedSchemaId, combinedSchema);
590
- }
591
- }
592
- getMatchingSchemas(document, jsonDocument, schema) {
593
- if (schema) {
594
- const id = schema.id || ('schemaservice://untitled/matchingSchemas/' + idCounter++);
595
- const handle = this.addSchemaHandle(id, schema);
596
- return handle.getResolvedSchema().then(resolvedSchema => {
597
- return jsonDocument.getMatchingSchemas(resolvedSchema.schema).filter(s => !s.inverted);
598
- });
599
- }
600
- return this.getSchemaForResource(document.uri, jsonDocument).then(schema => {
601
- if (schema) {
602
- return jsonDocument.getMatchingSchemas(schema.schema).filter(s => !s.inverted);
603
- }
604
- return [];
605
- });
606
- }
607
- }
608
- exports.JSONSchemaService = JSONSchemaService;
609
- let idCounter = 0;
610
- function normalizeResourceForMatching(resource) {
611
- // remove queries and fragments, normalize drive capitalization
612
- try {
613
- return vscode_uri_1.URI.parse(resource).with({ fragment: null, query: null }).toString(true);
614
- }
615
- catch (e) {
616
- return resource;
617
- }
618
- }
619
- function toDisplayString(url) {
620
- try {
621
- const uri = vscode_uri_1.URI.parse(url);
622
- if (uri.scheme === 'file') {
623
- return uri.fsPath;
624
- }
625
- }
626
- catch (e) {
627
- // ignore
628
- }
629
- return url;
630
- }
631
- });