vscode-json-languageservice 4.1.7 → 4.2.0-next.0

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.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
1
 
2
+
3
+ 4.2.0 /
4
+ ================
5
+ * new API `LanguageService.getLanguageStatus`
6
+
2
7
  4.1.6 / 2021-07-16
3
8
  ================
4
9
  * Replace minimatch with glob-to-regexp
@@ -1,4 +1,4 @@
1
- import { Thenable, ASTNode, Color, ColorInformation, ColorPresentation, LanguageServiceParams, LanguageSettings, DocumentLanguageSettings, FoldingRange, JSONSchema, SelectionRange, FoldingRangesContext, DocumentSymbolsContext, ColorInformationContext as DocumentColorsContext, TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, DocumentSymbol, DefinitionLink, MatchingSchema } from './jsonLanguageTypes';
1
+ import { Thenable, ASTNode, Color, ColorInformation, ColorPresentation, LanguageServiceParams, LanguageSettings, DocumentLanguageSettings, FoldingRange, JSONSchema, SelectionRange, FoldingRangesContext, DocumentSymbolsContext, ColorInformationContext as DocumentColorsContext, TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, DocumentSymbol, DefinitionLink, MatchingSchema, JSONLanguageStatus } from './jsonLanguageTypes';
2
2
  import { DocumentLink } from 'vscode-languageserver-types';
3
3
  export declare type JSONDocument = {
4
4
  root: ASTNode | undefined;
@@ -12,6 +12,7 @@ export interface LanguageService {
12
12
  newJSONDocument(rootNode: ASTNode, syntaxDiagnostics?: Diagnostic[]): JSONDocument;
13
13
  resetSchema(uri: string): boolean;
14
14
  getMatchingSchemas(document: TextDocument, jsonDocument: JSONDocument, schema?: JSONSchema): Thenable<MatchingSchema[]>;
15
+ getLanguageStatus(document: TextDocument, jsonDocument: JSONDocument): JSONLanguageStatus;
15
16
  doResolve(item: CompletionItem): Thenable<CompletionItem>;
16
17
  doComplete(document: TextDocument, position: Position, doc: JSONDocument): Thenable<CompletionList | null>;
17
18
  findDocumentSymbols(document: TextDocument, doc: JSONDocument, context?: DocumentSymbolsContext): SymbolInformation[];
@@ -35,6 +35,7 @@ export function getLanguageService(params) {
35
35
  },
36
36
  resetSchema: function (uri) { return jsonSchemaService.onResourceChange(uri); },
37
37
  doValidation: jsonValidation.doValidation.bind(jsonValidation),
38
+ getLanguageStatus: jsonValidation.getLanguageStatus.bind(jsonValidation),
38
39
  parseJSONDocument: function (document) { return parseJSON(document, { collectComments: true }); },
39
40
  newJSONDocument: function (root, diagnostics) { return newJSONDocument(root, diagnostics); },
40
41
  getMatchingSchemas: jsonSchemaService.getMatchingSchemas.bind(jsonSchemaService),
@@ -74,6 +74,9 @@ export interface MatchingSchema {
74
74
  node: ASTNode;
75
75
  schema: JSONSchema;
76
76
  }
77
+ export interface JSONLanguageStatus {
78
+ schemas: string[];
79
+ }
77
80
  export interface LanguageSettings {
78
81
  /**
79
82
  * If set, the validator will return syntax and semantic errors.
@@ -617,7 +617,7 @@ function validate(n, schema, validationResult, matchingSchemas) {
617
617
  }
618
618
  if (isString(schema.pattern)) {
619
619
  var regex = extendedRegExp(schema.pattern);
620
- if (!regex.test(node.value)) {
620
+ if (!(regex === null || regex === void 0 ? void 0 : regex.test(node.value))) {
621
621
  validationResult.problems.push({
622
622
  location: { offset: node.offset, length: node.length },
623
623
  message: schema.patternErrorMessage || schema.errorMessage || localize('patternWarning', 'String does not match the pattern of "{0}".', schema.pattern)
@@ -811,7 +811,7 @@ function validate(n, schema, validationResult, matchingSchemas) {
811
811
  var regex = extendedRegExp(propertyPattern);
812
812
  for (var _h = 0, _j = unprocessedProperties.slice(0); _h < _j.length; _h++) {
813
813
  var propertyName = _j[_h];
814
- if (regex.test(propertyName)) {
814
+ if (regex === null || regex === void 0 ? void 0 : regex.test(propertyName)) {
815
815
  propertyProcessed(propertyName);
816
816
  var child = seenKeys[propertyName];
817
817
  if (child) {
@@ -13,7 +13,6 @@ export var schemaContributions = {
13
13
  },
14
14
  // bundle the schema-schema to include (localized) descriptions
15
15
  'http://json-schema.org/draft-04/schema#': {
16
- 'title': localize('schema.json', 'Describes a JSON file using a schema. See json-schema.org for more info.'),
17
16
  '$schema': 'http://json-schema.org/draft-04/schema#',
18
17
  'definitions': {
19
18
  'schemaArray': {
@@ -297,7 +296,6 @@ export var schemaContributions = {
297
296
  'default': {}
298
297
  },
299
298
  'http://json-schema.org/draft-07/schema#': {
300
- 'title': localize('schema.json', 'Describes a JSON file using a schema. See json-schema.org for more info.'),
301
299
  'definitions': {
302
300
  'schemaArray': {
303
301
  'type': 'array',
@@ -440,7 +440,7 @@ var JSONCompletion = /** @class */ (function () {
440
440
  for (var _a = 0, _b = Object.keys(s.schema.patternProperties); _a < _b.length; _a++) {
441
441
  var pattern = _b[_a];
442
442
  var regex = extendedRegExp(pattern);
443
- if (regex.test(parentKey)) {
443
+ if (regex === null || regex === void 0 ? void 0 : regex.test(parentKey)) {
444
444
  propertyMatched = true;
445
445
  var propertySchema = s.schema.patternProperties[pattern];
446
446
  this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types);
@@ -55,17 +55,17 @@ var FilePatternAssociation = /** @class */ (function () {
55
55
  return FilePatternAssociation;
56
56
  }());
57
57
  var SchemaHandle = /** @class */ (function () {
58
- function SchemaHandle(service, url, unresolvedSchemaContent) {
58
+ function SchemaHandle(service, uri, unresolvedSchemaContent) {
59
59
  this.service = service;
60
- this.url = url;
61
- this.dependencies = {};
60
+ this.uri = uri;
61
+ this.dependencies = new Set();
62
62
  if (unresolvedSchemaContent) {
63
63
  this.unresolvedSchema = this.service.promise.resolve(new UnresolvedSchema(unresolvedSchemaContent));
64
64
  }
65
65
  }
66
66
  SchemaHandle.prototype.getUnresolvedSchema = function () {
67
67
  if (!this.unresolvedSchema) {
68
- this.unresolvedSchema = this.service.loadSchema(this.url);
68
+ this.unresolvedSchema = this.service.loadSchema(this.uri);
69
69
  }
70
70
  return this.unresolvedSchema;
71
71
  };
@@ -73,15 +73,17 @@ var SchemaHandle = /** @class */ (function () {
73
73
  var _this = this;
74
74
  if (!this.resolvedSchema) {
75
75
  this.resolvedSchema = this.getUnresolvedSchema().then(function (unresolved) {
76
- return _this.service.resolveSchemaContent(unresolved, _this.url, _this.dependencies);
76
+ return _this.service.resolveSchemaContent(unresolved, _this.uri, _this.dependencies);
77
77
  });
78
78
  }
79
79
  return this.resolvedSchema;
80
80
  };
81
81
  SchemaHandle.prototype.clearSchema = function () {
82
+ var hasChanges = !!this.unresolvedSchema;
82
83
  this.resolvedSchema = undefined;
83
84
  this.unresolvedSchema = undefined;
84
- this.dependencies = {};
85
+ this.dependencies.clear();
86
+ return hasChanges;
85
87
  };
86
88
  return SchemaHandle;
87
89
  }());
@@ -119,7 +121,7 @@ var ResolvedSchema = /** @class */ (function () {
119
121
  for (var _i = 0, _a = Object.keys(schema.patternProperties); _i < _a.length; _i++) {
120
122
  var pattern = _a[_i];
121
123
  var regex = Strings.extendedRegExp(pattern);
122
- if (regex.test(next)) {
124
+ if (regex === null || regex === void 0 ? void 0 : regex.test(next)) {
123
125
  return this.getSectionRecursive(path, schema.patternProperties[pattern]);
124
126
  }
125
127
  }
@@ -175,6 +177,8 @@ var JSONSchemaService = /** @class */ (function () {
175
177
  };
176
178
  JSONSchemaService.prototype.onResourceChange = function (uri) {
177
179
  var _this = this;
180
+ // always clear this local cache when a resource changes
181
+ this.cachedSchemaForResource = undefined;
178
182
  var hasChanges = false;
179
183
  uri = normalizeId(uri);
180
184
  var toWalk = [uri];
@@ -183,13 +187,14 @@ var JSONSchemaService = /** @class */ (function () {
183
187
  var curr = toWalk.pop();
184
188
  for (var i = 0; i < all.length; i++) {
185
189
  var handle = all[i];
186
- if (handle && (handle.url === curr || handle.dependencies[curr])) {
187
- if (handle.url !== curr) {
188
- toWalk.push(handle.url);
190
+ if (handle && (handle.uri === curr || handle.dependencies.has(curr))) {
191
+ if (handle.uri !== curr) {
192
+ toWalk.push(handle.uri);
193
+ }
194
+ if (handle.clearSchema()) {
195
+ hasChanges = true;
189
196
  }
190
- handle.clearSchema();
191
197
  all[i] = undefined;
192
- hasChanges = true;
193
198
  }
194
199
  }
195
200
  }
@@ -231,7 +236,7 @@ var JSONSchemaService = /** @class */ (function () {
231
236
  this.registeredSchemasIds[id] = true;
232
237
  this.cachedSchemaForResource = undefined;
233
238
  if (filePatterns) {
234
- this.addFilePatternAssociation(filePatterns, [uri]);
239
+ this.addFilePatternAssociation(filePatterns, [id]);
235
240
  }
236
241
  return unresolvedSchemaContent ? this.addSchemaHandle(id, unresolvedSchemaContent) : this.getOrAddSchemaHandle(id);
237
242
  };
@@ -297,6 +302,9 @@ var JSONSchemaService = /** @class */ (function () {
297
302
  else if (id === 'https://json-schema.org/draft/2019-09/schema') {
298
303
  resolveErrors.push(localize('json.schema.draft201909.notsupported', "Draft 2019-09 schemas are not yet fully supported."));
299
304
  }
305
+ else if (id === 'https://json-schema.org/draft/2020-12/schema') {
306
+ resolveErrors.push(localize('json.schema.draft202012.notsupported', "Draft 2020-12 schemas are not yet fully supported."));
307
+ }
300
308
  }
301
309
  var contextService = this.contextService;
302
310
  var findSection = function (schema, path) {
@@ -335,7 +343,7 @@ var JSONSchemaService = /** @class */ (function () {
335
343
  uri = normalizeId(uri);
336
344
  var referencedHandle = _this.getOrAddSchemaHandle(uri);
337
345
  return referencedHandle.getUnresolvedSchema().then(function (unresolvedSchema) {
338
- parentSchemaDependencies[uri] = true;
346
+ parentSchemaDependencies.add(uri);
339
347
  if (unresolvedSchema.errors.length) {
340
348
  var loc = refSegment ? uri + '#' + refSegment : uri;
341
349
  resolveErrors.push(localize('json.schema.problemloadingref', 'Problems loading reference \'{0}\': {1}', loc, unresolvedSchema.errors[0]));
@@ -349,7 +357,7 @@ var JSONSchemaService = /** @class */ (function () {
349
357
  return Promise.resolve(null);
350
358
  }
351
359
  var toWalk = [node];
352
- var seen = [];
360
+ var seen = new Set();
353
361
  var openPromises = [];
354
362
  var collectEntries = function () {
355
363
  var entries = [];
@@ -399,7 +407,7 @@ var JSONSchemaService = /** @class */ (function () {
399
407
  }
400
408
  };
401
409
  var handleRef = function (next) {
402
- var seenRefs = [];
410
+ var seenRefs = new Set();
403
411
  while (next.$ref) {
404
412
  var ref = next.$ref;
405
413
  var segments = ref.split('#', 2);
@@ -409,9 +417,9 @@ var JSONSchemaService = /** @class */ (function () {
409
417
  return;
410
418
  }
411
419
  else {
412
- if (seenRefs.indexOf(ref) === -1) {
420
+ if (!seenRefs.has(ref)) {
413
421
  merge(next, parentSchema, parentSchemaURL, segments[1]); // can set next.$ref again, use seenRefs to avoid circle
414
- seenRefs.push(ref);
422
+ seenRefs.add(ref);
415
423
  }
416
424
  }
417
425
  }
@@ -421,37 +429,29 @@ var JSONSchemaService = /** @class */ (function () {
421
429
  };
422
430
  while (toWalk.length) {
423
431
  var next = toWalk.pop();
424
- if (seen.indexOf(next) >= 0) {
432
+ if (seen.has(next)) {
425
433
  continue;
426
434
  }
427
- seen.push(next);
435
+ seen.add(next);
428
436
  handleRef(next);
429
437
  }
430
438
  return _this.promise.all(openPromises);
431
439
  };
432
440
  return resolveRefs(schema, schema, schemaURL, dependencies).then(function (_) { return new ResolvedSchema(schema, resolveErrors); });
433
441
  };
434
- JSONSchemaService.prototype.getSchemaForResource = function (resource, document) {
435
- // first use $schema if present
436
- if (document && document.root && document.root.type === 'object') {
437
- var schemaProperties = document.root.properties.filter(function (p) { return (p.keyNode.value === '$schema') && p.valueNode && p.valueNode.type === 'string'; });
438
- if (schemaProperties.length > 0) {
439
- var valueNode = schemaProperties[0].valueNode;
440
- if (valueNode && valueNode.type === 'string') {
441
- var schemeId = Parser.getNodeValue(valueNode);
442
- if (schemeId && Strings.startsWith(schemeId, '.') && this.contextService) {
443
- schemeId = this.contextService.resolveRelativePath(schemeId, resource);
444
- }
445
- if (schemeId) {
446
- var id = normalizeId(schemeId);
447
- return this.getOrAddSchemaHandle(id).getResolvedSchema();
448
- }
442
+ JSONSchemaService.prototype.getSchemaProperty = function (document) {
443
+ var _a, _b;
444
+ if (((_a = document.root) === null || _a === void 0 ? void 0 : _a.type) === 'object') {
445
+ for (var _i = 0, _c = document.root.properties; _i < _c.length; _i++) {
446
+ var p = _c[_i];
447
+ if (p.keyNode.value === '$schema' && ((_b = p.valueNode) === null || _b === void 0 ? void 0 : _b.type) === 'string') {
448
+ return p.valueNode.value;
449
449
  }
450
450
  }
451
451
  }
452
- if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
453
- return this.cachedSchemaForResource.resolvedSchema;
454
- }
452
+ return undefined;
453
+ };
454
+ JSONSchemaService.prototype.getAssociatedSchemas = function (resource) {
455
455
  var seen = Object.create(null);
456
456
  var schemas = [];
457
457
  var normalizedResource = normalizeResourceForMatching(resource);
@@ -467,6 +467,31 @@ var JSONSchemaService = /** @class */ (function () {
467
467
  }
468
468
  }
469
469
  }
470
+ return schemas;
471
+ };
472
+ JSONSchemaService.prototype.getSchemaURIsForResource = function (resource, document) {
473
+ var schemeId = document && this.getSchemaProperty(document);
474
+ if (schemeId) {
475
+ return [schemeId];
476
+ }
477
+ return this.getAssociatedSchemas(resource);
478
+ };
479
+ JSONSchemaService.prototype.getSchemaForResource = function (resource, document) {
480
+ if (document) {
481
+ // first use $schema if present
482
+ var schemeId = this.getSchemaProperty(document);
483
+ if (schemeId && Strings.startsWith(schemeId, '.') && this.contextService) {
484
+ schemeId = this.contextService.resolveRelativePath(schemeId, resource);
485
+ }
486
+ if (schemeId) {
487
+ var id = normalizeId(schemeId);
488
+ return this.getOrAddSchemaHandle(id).getResolvedSchema();
489
+ }
490
+ }
491
+ if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
492
+ return this.cachedSchemaForResource.resolvedSchema;
493
+ }
494
+ var schemas = this.getAssociatedSchemas(resource);
470
495
  var resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
471
496
  this.cachedSchemaForResource = { resource: resource, resolvedSchema: resolvedSchema };
472
497
  return resolvedSchema;
@@ -486,7 +511,7 @@ var JSONSchemaService = /** @class */ (function () {
486
511
  JSONSchemaService.prototype.getMatchingSchemas = function (document, jsonDocument, schema) {
487
512
  if (schema) {
488
513
  var id = schema.id || ('schemaservice://untitled/matchingSchemas/' + idCounter++);
489
- return this.resolveSchemaContent(new UnresolvedSchema(schema), id, {}).then(function (resolvedSchema) {
514
+ return this.resolveSchemaContent(new UnresolvedSchema(schema), id, new Set()).then(function (resolvedSchema) {
490
515
  return jsonDocument.getMatchingSchemas(resolvedSchema.schema).filter(function (s) { return !s.inverted; });
491
516
  });
492
517
  }
@@ -86,7 +86,7 @@ var JSONValidation = /** @class */ (function () {
86
86
  };
87
87
  if (schema) {
88
88
  var id = schema.id || ('schemaservice://untitled/' + idCounter++);
89
- return this.jsonSchemaService.resolveSchemaContent(new UnresolvedSchema(schema), id, {}).then(function (resolvedSchema) {
89
+ return this.jsonSchemaService.resolveSchemaContent(new UnresolvedSchema(schema), id, new Set()).then(function (resolvedSchema) {
90
90
  return getDiagnostics(resolvedSchema);
91
91
  });
92
92
  }
@@ -94,6 +94,9 @@ var JSONValidation = /** @class */ (function () {
94
94
  return getDiagnostics(schema);
95
95
  });
96
96
  };
97
+ JSONValidation.prototype.getLanguageStatus = function (textDocument, jsonDocument) {
98
+ return { schemas: this.jsonSchemaService.getSchemaURIsForResource(textDocument.uri, jsonDocument) };
99
+ };
97
100
  return JSONValidation;
98
101
  }());
99
102
  export { JSONValidation };
@@ -43,10 +43,22 @@ export function repeat(value, count) {
43
43
  return s;
44
44
  }
45
45
  export function extendedRegExp(pattern) {
46
+ var flags = '';
46
47
  if (startsWith(pattern, '(?i)')) {
47
- return new RegExp(pattern.substring(4), 'i');
48
+ pattern = pattern.substring(4);
49
+ flags = 'i';
48
50
  }
49
- else {
50
- return new RegExp(pattern);
51
+ try {
52
+ return new RegExp(pattern, flags + 'u');
53
+ }
54
+ catch (e) {
55
+ // could be an exception due to the 'u ' flag
56
+ try {
57
+ return new RegExp(pattern, flags);
58
+ }
59
+ catch (e) {
60
+ // invalid pattern
61
+ return undefined;
62
+ }
51
63
  }
52
64
  }
@@ -1,4 +1,4 @@
1
- import { Thenable, ASTNode, Color, ColorInformation, ColorPresentation, LanguageServiceParams, LanguageSettings, DocumentLanguageSettings, FoldingRange, JSONSchema, SelectionRange, FoldingRangesContext, DocumentSymbolsContext, ColorInformationContext as DocumentColorsContext, TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, DocumentSymbol, DefinitionLink, MatchingSchema } from './jsonLanguageTypes';
1
+ import { Thenable, ASTNode, Color, ColorInformation, ColorPresentation, LanguageServiceParams, LanguageSettings, DocumentLanguageSettings, FoldingRange, JSONSchema, SelectionRange, FoldingRangesContext, DocumentSymbolsContext, ColorInformationContext as DocumentColorsContext, TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, DocumentSymbol, DefinitionLink, MatchingSchema, JSONLanguageStatus } from './jsonLanguageTypes';
2
2
  import { DocumentLink } from 'vscode-languageserver-types';
3
3
  export declare type JSONDocument = {
4
4
  root: ASTNode | undefined;
@@ -12,6 +12,7 @@ export interface LanguageService {
12
12
  newJSONDocument(rootNode: ASTNode, syntaxDiagnostics?: Diagnostic[]): JSONDocument;
13
13
  resetSchema(uri: string): boolean;
14
14
  getMatchingSchemas(document: TextDocument, jsonDocument: JSONDocument, schema?: JSONSchema): Thenable<MatchingSchema[]>;
15
+ getLanguageStatus(document: TextDocument, jsonDocument: JSONDocument): JSONLanguageStatus;
15
16
  doResolve(item: CompletionItem): Thenable<CompletionItem>;
16
17
  doComplete(document: TextDocument, position: Position, doc: JSONDocument): Thenable<CompletionList | null>;
17
18
  findDocumentSymbols(document: TextDocument, doc: JSONDocument, context?: DocumentSymbolsContext): SymbolInformation[];
@@ -57,6 +57,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
57
57
  },
58
58
  resetSchema: function (uri) { return jsonSchemaService.onResourceChange(uri); },
59
59
  doValidation: jsonValidation.doValidation.bind(jsonValidation),
60
+ getLanguageStatus: jsonValidation.getLanguageStatus.bind(jsonValidation),
60
61
  parseJSONDocument: function (document) { return jsonParser_1.parse(document, { collectComments: true }); },
61
62
  newJSONDocument: function (root, diagnostics) { return jsonParser_1.newJSONDocument(root, diagnostics); },
62
63
  getMatchingSchemas: jsonSchemaService.getMatchingSchemas.bind(jsonSchemaService),
@@ -74,6 +74,9 @@ export interface MatchingSchema {
74
74
  node: ASTNode;
75
75
  schema: JSONSchema;
76
76
  }
77
+ export interface JSONLanguageStatus {
78
+ schemas: string[];
79
+ }
77
80
  export interface LanguageSettings {
78
81
  /**
79
82
  * If set, the validator will return syntax and semantic errors.
@@ -634,7 +634,7 @@ var __extends = (this && this.__extends) || (function () {
634
634
  }
635
635
  if (objects_1.isString(schema.pattern)) {
636
636
  var regex = strings_1.extendedRegExp(schema.pattern);
637
- if (!regex.test(node.value)) {
637
+ if (!(regex === null || regex === void 0 ? void 0 : regex.test(node.value))) {
638
638
  validationResult.problems.push({
639
639
  location: { offset: node.offset, length: node.length },
640
640
  message: schema.patternErrorMessage || schema.errorMessage || localize('patternWarning', 'String does not match the pattern of "{0}".', schema.pattern)
@@ -828,7 +828,7 @@ var __extends = (this && this.__extends) || (function () {
828
828
  var regex = strings_1.extendedRegExp(propertyPattern);
829
829
  for (var _h = 0, _j = unprocessedProperties.slice(0); _h < _j.length; _h++) {
830
830
  var propertyName = _j[_h];
831
- if (regex.test(propertyName)) {
831
+ if (regex === null || regex === void 0 ? void 0 : regex.test(propertyName)) {
832
832
  propertyProcessed(propertyName);
833
833
  var child = seenKeys[propertyName];
834
834
  if (child) {
@@ -25,7 +25,6 @@
25
25
  },
26
26
  // bundle the schema-schema to include (localized) descriptions
27
27
  'http://json-schema.org/draft-04/schema#': {
28
- 'title': localize('schema.json', 'Describes a JSON file using a schema. See json-schema.org for more info.'),
29
28
  '$schema': 'http://json-schema.org/draft-04/schema#',
30
29
  'definitions': {
31
30
  'schemaArray': {
@@ -309,7 +308,6 @@
309
308
  'default': {}
310
309
  },
311
310
  'http://json-schema.org/draft-07/schema#': {
312
- 'title': localize('schema.json', 'Describes a JSON file using a schema. See json-schema.org for more info.'),
313
311
  'definitions': {
314
312
  'schemaArray': {
315
313
  'type': 'array',
@@ -452,7 +452,7 @@
452
452
  for (var _a = 0, _b = Object.keys(s.schema.patternProperties); _a < _b.length; _a++) {
453
453
  var pattern = _b[_a];
454
454
  var regex = strings_1.extendedRegExp(pattern);
455
- if (regex.test(parentKey)) {
455
+ if (regex === null || regex === void 0 ? void 0 : regex.test(parentKey)) {
456
456
  propertyMatched = true;
457
457
  var propertySchema = s.schema.patternProperties[pattern];
458
458
  this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types);
@@ -67,17 +67,17 @@
67
67
  return FilePatternAssociation;
68
68
  }());
69
69
  var SchemaHandle = /** @class */ (function () {
70
- function SchemaHandle(service, url, unresolvedSchemaContent) {
70
+ function SchemaHandle(service, uri, unresolvedSchemaContent) {
71
71
  this.service = service;
72
- this.url = url;
73
- this.dependencies = {};
72
+ this.uri = uri;
73
+ this.dependencies = new Set();
74
74
  if (unresolvedSchemaContent) {
75
75
  this.unresolvedSchema = this.service.promise.resolve(new UnresolvedSchema(unresolvedSchemaContent));
76
76
  }
77
77
  }
78
78
  SchemaHandle.prototype.getUnresolvedSchema = function () {
79
79
  if (!this.unresolvedSchema) {
80
- this.unresolvedSchema = this.service.loadSchema(this.url);
80
+ this.unresolvedSchema = this.service.loadSchema(this.uri);
81
81
  }
82
82
  return this.unresolvedSchema;
83
83
  };
@@ -85,15 +85,17 @@
85
85
  var _this = this;
86
86
  if (!this.resolvedSchema) {
87
87
  this.resolvedSchema = this.getUnresolvedSchema().then(function (unresolved) {
88
- return _this.service.resolveSchemaContent(unresolved, _this.url, _this.dependencies);
88
+ return _this.service.resolveSchemaContent(unresolved, _this.uri, _this.dependencies);
89
89
  });
90
90
  }
91
91
  return this.resolvedSchema;
92
92
  };
93
93
  SchemaHandle.prototype.clearSchema = function () {
94
+ var hasChanges = !!this.unresolvedSchema;
94
95
  this.resolvedSchema = undefined;
95
96
  this.unresolvedSchema = undefined;
96
- this.dependencies = {};
97
+ this.dependencies.clear();
98
+ return hasChanges;
97
99
  };
98
100
  return SchemaHandle;
99
101
  }());
@@ -131,7 +133,7 @@
131
133
  for (var _i = 0, _a = Object.keys(schema.patternProperties); _i < _a.length; _i++) {
132
134
  var pattern = _a[_i];
133
135
  var regex = Strings.extendedRegExp(pattern);
134
- if (regex.test(next)) {
136
+ if (regex === null || regex === void 0 ? void 0 : regex.test(next)) {
135
137
  return this.getSectionRecursive(path, schema.patternProperties[pattern]);
136
138
  }
137
139
  }
@@ -187,6 +189,8 @@
187
189
  };
188
190
  JSONSchemaService.prototype.onResourceChange = function (uri) {
189
191
  var _this = this;
192
+ // always clear this local cache when a resource changes
193
+ this.cachedSchemaForResource = undefined;
190
194
  var hasChanges = false;
191
195
  uri = normalizeId(uri);
192
196
  var toWalk = [uri];
@@ -195,13 +199,14 @@
195
199
  var curr = toWalk.pop();
196
200
  for (var i = 0; i < all.length; i++) {
197
201
  var handle = all[i];
198
- if (handle && (handle.url === curr || handle.dependencies[curr])) {
199
- if (handle.url !== curr) {
200
- toWalk.push(handle.url);
202
+ if (handle && (handle.uri === curr || handle.dependencies.has(curr))) {
203
+ if (handle.uri !== curr) {
204
+ toWalk.push(handle.uri);
205
+ }
206
+ if (handle.clearSchema()) {
207
+ hasChanges = true;
201
208
  }
202
- handle.clearSchema();
203
209
  all[i] = undefined;
204
- hasChanges = true;
205
210
  }
206
211
  }
207
212
  }
@@ -243,7 +248,7 @@
243
248
  this.registeredSchemasIds[id] = true;
244
249
  this.cachedSchemaForResource = undefined;
245
250
  if (filePatterns) {
246
- this.addFilePatternAssociation(filePatterns, [uri]);
251
+ this.addFilePatternAssociation(filePatterns, [id]);
247
252
  }
248
253
  return unresolvedSchemaContent ? this.addSchemaHandle(id, unresolvedSchemaContent) : this.getOrAddSchemaHandle(id);
249
254
  };
@@ -309,6 +314,9 @@
309
314
  else if (id === 'https://json-schema.org/draft/2019-09/schema') {
310
315
  resolveErrors.push(localize('json.schema.draft201909.notsupported', "Draft 2019-09 schemas are not yet fully supported."));
311
316
  }
317
+ else if (id === 'https://json-schema.org/draft/2020-12/schema') {
318
+ resolveErrors.push(localize('json.schema.draft202012.notsupported', "Draft 2020-12 schemas are not yet fully supported."));
319
+ }
312
320
  }
313
321
  var contextService = this.contextService;
314
322
  var findSection = function (schema, path) {
@@ -347,7 +355,7 @@
347
355
  uri = normalizeId(uri);
348
356
  var referencedHandle = _this.getOrAddSchemaHandle(uri);
349
357
  return referencedHandle.getUnresolvedSchema().then(function (unresolvedSchema) {
350
- parentSchemaDependencies[uri] = true;
358
+ parentSchemaDependencies.add(uri);
351
359
  if (unresolvedSchema.errors.length) {
352
360
  var loc = refSegment ? uri + '#' + refSegment : uri;
353
361
  resolveErrors.push(localize('json.schema.problemloadingref', 'Problems loading reference \'{0}\': {1}', loc, unresolvedSchema.errors[0]));
@@ -361,7 +369,7 @@
361
369
  return Promise.resolve(null);
362
370
  }
363
371
  var toWalk = [node];
364
- var seen = [];
372
+ var seen = new Set();
365
373
  var openPromises = [];
366
374
  var collectEntries = function () {
367
375
  var entries = [];
@@ -411,7 +419,7 @@
411
419
  }
412
420
  };
413
421
  var handleRef = function (next) {
414
- var seenRefs = [];
422
+ var seenRefs = new Set();
415
423
  while (next.$ref) {
416
424
  var ref = next.$ref;
417
425
  var segments = ref.split('#', 2);
@@ -421,9 +429,9 @@
421
429
  return;
422
430
  }
423
431
  else {
424
- if (seenRefs.indexOf(ref) === -1) {
432
+ if (!seenRefs.has(ref)) {
425
433
  merge(next, parentSchema, parentSchemaURL, segments[1]); // can set next.$ref again, use seenRefs to avoid circle
426
- seenRefs.push(ref);
434
+ seenRefs.add(ref);
427
435
  }
428
436
  }
429
437
  }
@@ -433,37 +441,29 @@
433
441
  };
434
442
  while (toWalk.length) {
435
443
  var next = toWalk.pop();
436
- if (seen.indexOf(next) >= 0) {
444
+ if (seen.has(next)) {
437
445
  continue;
438
446
  }
439
- seen.push(next);
447
+ seen.add(next);
440
448
  handleRef(next);
441
449
  }
442
450
  return _this.promise.all(openPromises);
443
451
  };
444
452
  return resolveRefs(schema, schema, schemaURL, dependencies).then(function (_) { return new ResolvedSchema(schema, resolveErrors); });
445
453
  };
446
- JSONSchemaService.prototype.getSchemaForResource = function (resource, document) {
447
- // first use $schema if present
448
- if (document && document.root && document.root.type === 'object') {
449
- var schemaProperties = document.root.properties.filter(function (p) { return (p.keyNode.value === '$schema') && p.valueNode && p.valueNode.type === 'string'; });
450
- if (schemaProperties.length > 0) {
451
- var valueNode = schemaProperties[0].valueNode;
452
- if (valueNode && valueNode.type === 'string') {
453
- var schemeId = Parser.getNodeValue(valueNode);
454
- if (schemeId && Strings.startsWith(schemeId, '.') && this.contextService) {
455
- schemeId = this.contextService.resolveRelativePath(schemeId, resource);
456
- }
457
- if (schemeId) {
458
- var id = normalizeId(schemeId);
459
- return this.getOrAddSchemaHandle(id).getResolvedSchema();
460
- }
454
+ JSONSchemaService.prototype.getSchemaProperty = function (document) {
455
+ var _a, _b;
456
+ if (((_a = document.root) === null || _a === void 0 ? void 0 : _a.type) === 'object') {
457
+ for (var _i = 0, _c = document.root.properties; _i < _c.length; _i++) {
458
+ var p = _c[_i];
459
+ if (p.keyNode.value === '$schema' && ((_b = p.valueNode) === null || _b === void 0 ? void 0 : _b.type) === 'string') {
460
+ return p.valueNode.value;
461
461
  }
462
462
  }
463
463
  }
464
- if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
465
- return this.cachedSchemaForResource.resolvedSchema;
466
- }
464
+ return undefined;
465
+ };
466
+ JSONSchemaService.prototype.getAssociatedSchemas = function (resource) {
467
467
  var seen = Object.create(null);
468
468
  var schemas = [];
469
469
  var normalizedResource = normalizeResourceForMatching(resource);
@@ -479,6 +479,31 @@
479
479
  }
480
480
  }
481
481
  }
482
+ return schemas;
483
+ };
484
+ JSONSchemaService.prototype.getSchemaURIsForResource = function (resource, document) {
485
+ var schemeId = document && this.getSchemaProperty(document);
486
+ if (schemeId) {
487
+ return [schemeId];
488
+ }
489
+ return this.getAssociatedSchemas(resource);
490
+ };
491
+ JSONSchemaService.prototype.getSchemaForResource = function (resource, document) {
492
+ if (document) {
493
+ // first use $schema if present
494
+ var schemeId = this.getSchemaProperty(document);
495
+ if (schemeId && Strings.startsWith(schemeId, '.') && this.contextService) {
496
+ schemeId = this.contextService.resolveRelativePath(schemeId, resource);
497
+ }
498
+ if (schemeId) {
499
+ var id = normalizeId(schemeId);
500
+ return this.getOrAddSchemaHandle(id).getResolvedSchema();
501
+ }
502
+ }
503
+ if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
504
+ return this.cachedSchemaForResource.resolvedSchema;
505
+ }
506
+ var schemas = this.getAssociatedSchemas(resource);
482
507
  var resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
483
508
  this.cachedSchemaForResource = { resource: resource, resolvedSchema: resolvedSchema };
484
509
  return resolvedSchema;
@@ -498,7 +523,7 @@
498
523
  JSONSchemaService.prototype.getMatchingSchemas = function (document, jsonDocument, schema) {
499
524
  if (schema) {
500
525
  var id = schema.id || ('schemaservice://untitled/matchingSchemas/' + idCounter++);
501
- return this.resolveSchemaContent(new UnresolvedSchema(schema), id, {}).then(function (resolvedSchema) {
526
+ return this.resolveSchemaContent(new UnresolvedSchema(schema), id, new Set()).then(function (resolvedSchema) {
502
527
  return jsonDocument.getMatchingSchemas(resolvedSchema.schema).filter(function (s) { return !s.inverted; });
503
528
  });
504
529
  }
@@ -98,7 +98,7 @@
98
98
  };
99
99
  if (schema) {
100
100
  var id = schema.id || ('schemaservice://untitled/' + idCounter++);
101
- return this.jsonSchemaService.resolveSchemaContent(new jsonSchemaService_1.UnresolvedSchema(schema), id, {}).then(function (resolvedSchema) {
101
+ return this.jsonSchemaService.resolveSchemaContent(new jsonSchemaService_1.UnresolvedSchema(schema), id, new Set()).then(function (resolvedSchema) {
102
102
  return getDiagnostics(resolvedSchema);
103
103
  });
104
104
  }
@@ -106,6 +106,9 @@
106
106
  return getDiagnostics(schema);
107
107
  });
108
108
  };
109
+ JSONValidation.prototype.getLanguageStatus = function (textDocument, jsonDocument) {
110
+ return { schemas: this.jsonSchemaService.getSchemaURIsForResource(textDocument.uri, jsonDocument) };
111
+ };
109
112
  return JSONValidation;
110
113
  }());
111
114
  exports.JSONValidation = JSONValidation;
@@ -59,11 +59,23 @@
59
59
  }
60
60
  exports.repeat = repeat;
61
61
  function extendedRegExp(pattern) {
62
+ var flags = '';
62
63
  if (startsWith(pattern, '(?i)')) {
63
- return new RegExp(pattern.substring(4), 'i');
64
+ pattern = pattern.substring(4);
65
+ flags = 'i';
64
66
  }
65
- else {
66
- return new RegExp(pattern);
67
+ try {
68
+ return new RegExp(pattern, flags + 'u');
69
+ }
70
+ catch (e) {
71
+ // could be an exception due to the 'u ' flag
72
+ try {
73
+ return new RegExp(pattern, flags);
74
+ }
75
+ catch (e) {
76
+ // invalid pattern
77
+ return undefined;
78
+ }
67
79
  }
68
80
  }
69
81
  exports.extendedRegExp = extendedRegExp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vscode-json-languageservice",
3
- "version": "4.1.7",
3
+ "version": "4.2.0-next.0",
4
4
  "description": "Language service for JSON",
5
5
  "main": "./lib/umd/jsonLanguageService.js",
6
6
  "typings": "./lib/umd/jsonLanguageService",
@@ -14,16 +14,13 @@
14
14
  "bugs": {
15
15
  "url": "https://github.com/Microsoft/vscode-json-languageservice"
16
16
  },
17
- "engines": {
18
- "npm": ">=7.0.0"
19
- },
20
17
  "devDependencies": {
21
- "@types/mocha": "^8.2.0",
18
+ "@types/mocha": "^9.0.0",
22
19
  "@types/node": "^10.12.21",
23
- "@typescript-eslint/eslint-plugin": "^4.14.0",
24
- "@typescript-eslint/parser": "^4.14.0",
25
- "eslint": "^7.18.0",
26
- "mocha": "^8.2.1",
20
+ "@typescript-eslint/eslint-plugin": "^4.32.0",
21
+ "@typescript-eslint/parser": "^4.32.0",
22
+ "eslint": "^7.32.0",
23
+ "mocha": "^9.1.2",
27
24
  "rimraf": "^3.0.2",
28
25
  "typescript": "^4.1.3"
29
26
  },