vscode-json-languageservice 4.2.0 → 5.1.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/SECURITY.md +41 -0
  3. package/lib/esm/jsonLanguageService.js +22 -22
  4. package/lib/esm/jsonLanguageTypes.d.ts +3 -1
  5. package/lib/esm/jsonLanguageTypes.js +3 -2
  6. package/lib/esm/jsonSchema.d.ts +21 -2
  7. package/lib/esm/parser/jsonParser.js +488 -488
  8. package/lib/esm/services/configuration.js +9 -9
  9. package/lib/esm/services/jsonCompletion.js +280 -290
  10. package/lib/esm/services/jsonDocumentSymbols.js +88 -99
  11. package/lib/esm/services/jsonFolding.js +38 -39
  12. package/lib/esm/services/jsonHover.js +40 -43
  13. package/lib/esm/services/jsonLinks.js +12 -13
  14. package/lib/esm/services/jsonSchemaService.js +234 -253
  15. package/lib/esm/services/jsonSelectionRanges.js +9 -9
  16. package/lib/esm/services/jsonValidation.js +53 -51
  17. package/lib/esm/utils/colors.js +7 -8
  18. package/lib/esm/utils/glob.js +12 -12
  19. package/lib/esm/utils/json.js +7 -7
  20. package/lib/esm/utils/objects.js +3 -0
  21. package/lib/esm/utils/strings.js +3 -3
  22. package/lib/umd/jsonLanguageService.js +36 -32
  23. package/lib/umd/jsonLanguageTypes.d.ts +3 -1
  24. package/lib/umd/jsonLanguageTypes.js +5 -3
  25. package/lib/umd/jsonSchema.d.ts +21 -2
  26. package/lib/umd/parser/jsonParser.js +492 -482
  27. package/lib/umd/services/configuration.js +9 -9
  28. package/lib/umd/services/jsonCompletion.js +287 -296
  29. package/lib/umd/services/jsonDocumentSymbols.js +92 -102
  30. package/lib/umd/services/jsonFolding.js +40 -41
  31. package/lib/umd/services/jsonHover.js +42 -44
  32. package/lib/umd/services/jsonLinks.js +13 -14
  33. package/lib/umd/services/jsonSchemaService.js +241 -257
  34. package/lib/umd/services/jsonSelectionRanges.js +11 -11
  35. package/lib/umd/services/jsonValidation.js +56 -53
  36. package/lib/umd/utils/colors.js +7 -8
  37. package/lib/umd/utils/glob.js +12 -12
  38. package/lib/umd/utils/json.js +7 -7
  39. package/lib/umd/utils/objects.js +5 -1
  40. package/lib/umd/utils/strings.js +3 -3
  41. package/package.json +12 -12
@@ -2,28 +2,13 @@
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
- var __extends = (this && this.__extends) || (function () {
6
- var extendStatics = function (d, b) {
7
- extendStatics = Object.setPrototypeOf ||
8
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
9
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
10
- return extendStatics(d, b);
11
- };
12
- return function (d, b) {
13
- if (typeof b !== "function" && b !== null)
14
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
15
- extendStatics(d, b);
16
- function __() { this.constructor = d; }
17
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
18
- };
19
- })();
20
5
  import * as Json from 'jsonc-parser';
21
- import { isNumber, equals, isBoolean, isString, isDefined } from '../utils/objects';
6
+ import { isNumber, equals, isBoolean, isString, isDefined, isObject } from '../utils/objects';
22
7
  import { extendedRegExp } from '../utils/strings';
23
8
  import { ErrorCode, Diagnostic, DiagnosticSeverity, Range } from '../jsonLanguageTypes';
24
9
  import * as nls from 'vscode-nls';
25
- var localize = nls.loadMessageBundle();
26
- var formats = {
10
+ const localize = nls.loadMessageBundle();
11
+ const formats = {
27
12
  'color-hex': { errorMessage: localize('colorHexFormatWarning', 'Invalid color format. Use #RGB, #RGBA, #RRGGBB or #RRGGBBAA.'), pattern: /^#([0-9A-Fa-f]{3,4}|([0-9A-Fa-f]{2}){3,4})$/ },
28
13
  'date-time': { errorMessage: localize('dateTimeFormatWarning', 'String is not a RFC3339 date-time.'), pattern: /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/i },
29
14
  'date': { errorMessage: localize('dateFormatWarning', 'String is not a RFC3339 date.'), pattern: /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/i },
@@ -33,126 +18,79 @@ var formats = {
33
18
  'ipv4': { errorMessage: localize('ipv4FormatWarning', 'String is not an IPv4 address.'), pattern: /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/ },
34
19
  'ipv6': { errorMessage: localize('ipv6FormatWarning', 'String is not an IPv6 address.'), pattern: /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i },
35
20
  };
36
- var ASTNodeImpl = /** @class */ (function () {
37
- function ASTNodeImpl(parent, offset, length) {
38
- if (length === void 0) { length = 0; }
21
+ export class ASTNodeImpl {
22
+ constructor(parent, offset, length = 0) {
39
23
  this.offset = offset;
40
24
  this.length = length;
41
25
  this.parent = parent;
42
26
  }
43
- Object.defineProperty(ASTNodeImpl.prototype, "children", {
44
- get: function () {
45
- return [];
46
- },
47
- enumerable: false,
48
- configurable: true
49
- });
50
- ASTNodeImpl.prototype.toString = function () {
27
+ get children() {
28
+ return [];
29
+ }
30
+ toString() {
51
31
  return 'type: ' + this.type + ' (' + this.offset + '/' + this.length + ')' + (this.parent ? ' parent: {' + this.parent.toString() + '}' : '');
52
- };
53
- return ASTNodeImpl;
54
- }());
55
- export { ASTNodeImpl };
56
- var NullASTNodeImpl = /** @class */ (function (_super) {
57
- __extends(NullASTNodeImpl, _super);
58
- function NullASTNodeImpl(parent, offset) {
59
- var _this = _super.call(this, parent, offset) || this;
60
- _this.type = 'null';
61
- _this.value = null;
62
- return _this;
63
32
  }
64
- return NullASTNodeImpl;
65
- }(ASTNodeImpl));
66
- export { NullASTNodeImpl };
67
- var BooleanASTNodeImpl = /** @class */ (function (_super) {
68
- __extends(BooleanASTNodeImpl, _super);
69
- function BooleanASTNodeImpl(parent, boolValue, offset) {
70
- var _this = _super.call(this, parent, offset) || this;
71
- _this.type = 'boolean';
72
- _this.value = boolValue;
73
- return _this;
33
+ }
34
+ export class NullASTNodeImpl extends ASTNodeImpl {
35
+ constructor(parent, offset) {
36
+ super(parent, offset);
37
+ this.type = 'null';
38
+ this.value = null;
39
+ }
40
+ }
41
+ export class BooleanASTNodeImpl extends ASTNodeImpl {
42
+ constructor(parent, boolValue, offset) {
43
+ super(parent, offset);
44
+ this.type = 'boolean';
45
+ this.value = boolValue;
46
+ }
47
+ }
48
+ export class ArrayASTNodeImpl extends ASTNodeImpl {
49
+ constructor(parent, offset) {
50
+ super(parent, offset);
51
+ this.type = 'array';
52
+ this.items = [];
53
+ }
54
+ get children() {
55
+ return this.items;
56
+ }
57
+ }
58
+ export class NumberASTNodeImpl extends ASTNodeImpl {
59
+ constructor(parent, offset) {
60
+ super(parent, offset);
61
+ this.type = 'number';
62
+ this.isInteger = true;
63
+ this.value = Number.NaN;
74
64
  }
75
- return BooleanASTNodeImpl;
76
- }(ASTNodeImpl));
77
- export { BooleanASTNodeImpl };
78
- var ArrayASTNodeImpl = /** @class */ (function (_super) {
79
- __extends(ArrayASTNodeImpl, _super);
80
- function ArrayASTNodeImpl(parent, offset) {
81
- var _this = _super.call(this, parent, offset) || this;
82
- _this.type = 'array';
83
- _this.items = [];
84
- return _this;
65
+ }
66
+ export class StringASTNodeImpl extends ASTNodeImpl {
67
+ constructor(parent, offset, length) {
68
+ super(parent, offset, length);
69
+ this.type = 'string';
70
+ this.value = '';
85
71
  }
86
- Object.defineProperty(ArrayASTNodeImpl.prototype, "children", {
87
- get: function () {
88
- return this.items;
89
- },
90
- enumerable: false,
91
- configurable: true
92
- });
93
- return ArrayASTNodeImpl;
94
- }(ASTNodeImpl));
95
- export { ArrayASTNodeImpl };
96
- var NumberASTNodeImpl = /** @class */ (function (_super) {
97
- __extends(NumberASTNodeImpl, _super);
98
- function NumberASTNodeImpl(parent, offset) {
99
- var _this = _super.call(this, parent, offset) || this;
100
- _this.type = 'number';
101
- _this.isInteger = true;
102
- _this.value = Number.NaN;
103
- return _this;
72
+ }
73
+ export class PropertyASTNodeImpl extends ASTNodeImpl {
74
+ constructor(parent, offset, keyNode) {
75
+ super(parent, offset);
76
+ this.type = 'property';
77
+ this.colonOffset = -1;
78
+ this.keyNode = keyNode;
104
79
  }
105
- return NumberASTNodeImpl;
106
- }(ASTNodeImpl));
107
- export { NumberASTNodeImpl };
108
- var StringASTNodeImpl = /** @class */ (function (_super) {
109
- __extends(StringASTNodeImpl, _super);
110
- function StringASTNodeImpl(parent, offset, length) {
111
- var _this = _super.call(this, parent, offset, length) || this;
112
- _this.type = 'string';
113
- _this.value = '';
114
- return _this;
80
+ get children() {
81
+ return this.valueNode ? [this.keyNode, this.valueNode] : [this.keyNode];
115
82
  }
116
- return StringASTNodeImpl;
117
- }(ASTNodeImpl));
118
- export { StringASTNodeImpl };
119
- var PropertyASTNodeImpl = /** @class */ (function (_super) {
120
- __extends(PropertyASTNodeImpl, _super);
121
- function PropertyASTNodeImpl(parent, offset, keyNode) {
122
- var _this = _super.call(this, parent, offset) || this;
123
- _this.type = 'property';
124
- _this.colonOffset = -1;
125
- _this.keyNode = keyNode;
126
- return _this;
83
+ }
84
+ export class ObjectASTNodeImpl extends ASTNodeImpl {
85
+ constructor(parent, offset) {
86
+ super(parent, offset);
87
+ this.type = 'object';
88
+ this.properties = [];
127
89
  }
128
- Object.defineProperty(PropertyASTNodeImpl.prototype, "children", {
129
- get: function () {
130
- return this.valueNode ? [this.keyNode, this.valueNode] : [this.keyNode];
131
- },
132
- enumerable: false,
133
- configurable: true
134
- });
135
- return PropertyASTNodeImpl;
136
- }(ASTNodeImpl));
137
- export { PropertyASTNodeImpl };
138
- var ObjectASTNodeImpl = /** @class */ (function (_super) {
139
- __extends(ObjectASTNodeImpl, _super);
140
- function ObjectASTNodeImpl(parent, offset) {
141
- var _this = _super.call(this, parent, offset) || this;
142
- _this.type = 'object';
143
- _this.properties = [];
144
- return _this;
90
+ get children() {
91
+ return this.properties;
145
92
  }
146
- Object.defineProperty(ObjectASTNodeImpl.prototype, "children", {
147
- get: function () {
148
- return this.properties;
149
- },
150
- enumerable: false,
151
- configurable: true
152
- });
153
- return ObjectASTNodeImpl;
154
- }(ASTNodeImpl));
155
- export { ObjectASTNodeImpl };
93
+ }
156
94
  export function asSchema(schema) {
157
95
  if (isBoolean(schema)) {
158
96
  return schema ? {} : { "not": {} };
@@ -164,75 +102,66 @@ export var EnumMatch;
164
102
  EnumMatch[EnumMatch["Key"] = 0] = "Key";
165
103
  EnumMatch[EnumMatch["Enum"] = 1] = "Enum";
166
104
  })(EnumMatch || (EnumMatch = {}));
167
- var SchemaCollector = /** @class */ (function () {
168
- function SchemaCollector(focusOffset, exclude) {
169
- if (focusOffset === void 0) { focusOffset = -1; }
105
+ class SchemaCollector {
106
+ constructor(focusOffset = -1, exclude) {
170
107
  this.focusOffset = focusOffset;
171
108
  this.exclude = exclude;
172
109
  this.schemas = [];
173
110
  }
174
- SchemaCollector.prototype.add = function (schema) {
111
+ add(schema) {
175
112
  this.schemas.push(schema);
176
- };
177
- SchemaCollector.prototype.merge = function (other) {
113
+ }
114
+ merge(other) {
178
115
  Array.prototype.push.apply(this.schemas, other.schemas);
179
- };
180
- SchemaCollector.prototype.include = function (node) {
116
+ }
117
+ include(node) {
181
118
  return (this.focusOffset === -1 || contains(node, this.focusOffset)) && (node !== this.exclude);
182
- };
183
- SchemaCollector.prototype.newSub = function () {
119
+ }
120
+ newSub() {
184
121
  return new SchemaCollector(-1, this.exclude);
185
- };
186
- return SchemaCollector;
187
- }());
188
- var NoOpSchemaCollector = /** @class */ (function () {
189
- function NoOpSchemaCollector() {
190
122
  }
191
- Object.defineProperty(NoOpSchemaCollector.prototype, "schemas", {
192
- get: function () { return []; },
193
- enumerable: false,
194
- configurable: true
195
- });
196
- NoOpSchemaCollector.prototype.add = function (schema) { };
197
- NoOpSchemaCollector.prototype.merge = function (other) { };
198
- NoOpSchemaCollector.prototype.include = function (node) { return true; };
199
- NoOpSchemaCollector.prototype.newSub = function () { return this; };
200
- NoOpSchemaCollector.instance = new NoOpSchemaCollector();
201
- return NoOpSchemaCollector;
202
- }());
203
- var ValidationResult = /** @class */ (function () {
204
- function ValidationResult() {
123
+ }
124
+ class NoOpSchemaCollector {
125
+ constructor() { }
126
+ get schemas() { return []; }
127
+ add(schema) { }
128
+ merge(other) { }
129
+ include(node) { return true; }
130
+ newSub() { return this; }
131
+ }
132
+ NoOpSchemaCollector.instance = new NoOpSchemaCollector();
133
+ export class ValidationResult {
134
+ constructor() {
205
135
  this.problems = [];
206
136
  this.propertiesMatches = 0;
137
+ this.processedProperties = new Set();
207
138
  this.propertiesValueMatches = 0;
208
139
  this.primaryValueMatches = 0;
209
140
  this.enumValueMatch = false;
210
141
  this.enumValues = undefined;
211
142
  }
212
- ValidationResult.prototype.hasProblems = function () {
143
+ hasProblems() {
213
144
  return !!this.problems.length;
214
- };
215
- ValidationResult.prototype.mergeAll = function (validationResults) {
216
- for (var _i = 0, validationResults_1 = validationResults; _i < validationResults_1.length; _i++) {
217
- var validationResult = validationResults_1[_i];
145
+ }
146
+ mergeAll(validationResults) {
147
+ for (const validationResult of validationResults) {
218
148
  this.merge(validationResult);
219
149
  }
220
- };
221
- ValidationResult.prototype.merge = function (validationResult) {
150
+ }
151
+ merge(validationResult) {
222
152
  this.problems = this.problems.concat(validationResult.problems);
223
- };
224
- ValidationResult.prototype.mergeEnumValues = function (validationResult) {
153
+ }
154
+ mergeEnumValues(validationResult) {
225
155
  if (!this.enumValueMatch && !validationResult.enumValueMatch && this.enumValues && validationResult.enumValues) {
226
156
  this.enumValues = this.enumValues.concat(validationResult.enumValues);
227
- for (var _i = 0, _a = this.problems; _i < _a.length; _i++) {
228
- var error = _a[_i];
157
+ for (const error of this.problems) {
229
158
  if (error.code === ErrorCode.EnumValueMismatch) {
230
- error.message = localize('enumWarning', 'Value is not accepted. Valid values: {0}.', this.enumValues.map(function (v) { return JSON.stringify(v); }).join(', '));
159
+ error.message = localize('enumWarning', 'Value is not accepted. Valid values: {0}.', this.enumValues.map(v => JSON.stringify(v)).join(', '));
231
160
  }
232
161
  }
233
162
  }
234
- };
235
- ValidationResult.prototype.mergePropertyMatch = function (propertyValidationResult) {
163
+ }
164
+ mergePropertyMatch(propertyValidationResult) {
236
165
  this.merge(propertyValidationResult);
237
166
  this.propertiesMatches++;
238
167
  if (propertyValidationResult.enumValueMatch || !propertyValidationResult.hasProblems() && propertyValidationResult.propertiesMatches) {
@@ -241,9 +170,12 @@ var ValidationResult = /** @class */ (function () {
241
170
  if (propertyValidationResult.enumValueMatch && propertyValidationResult.enumValues && propertyValidationResult.enumValues.length === 1) {
242
171
  this.primaryValueMatches++;
243
172
  }
244
- };
245
- ValidationResult.prototype.compare = function (other) {
246
- var hasProblems = this.hasProblems();
173
+ }
174
+ mergeProcessedProperties(validationResult) {
175
+ validationResult.processedProperties.forEach(p => this.processedProperties.add(p));
176
+ }
177
+ compare(other) {
178
+ const hasProblems = this.hasProblems();
247
179
  if (hasProblems !== other.hasProblems()) {
248
180
  return hasProblems ? -1 : 1;
249
181
  }
@@ -257,12 +189,9 @@ var ValidationResult = /** @class */ (function () {
257
189
  return this.propertiesValueMatches - other.propertiesValueMatches;
258
190
  }
259
191
  return this.propertiesMatches - other.propertiesMatches;
260
- };
261
- return ValidationResult;
262
- }());
263
- export { ValidationResult };
264
- export function newJSONDocument(root, diagnostics) {
265
- if (diagnostics === void 0) { diagnostics = []; }
192
+ }
193
+ }
194
+ export function newJSONDocument(root, diagnostics = []) {
266
195
  return new JSONDocument(root, diagnostics, []);
267
196
  }
268
197
  export function getNodeValue(node) {
@@ -271,86 +200,78 @@ export function getNodeValue(node) {
271
200
  export function getNodePath(node) {
272
201
  return Json.getNodePath(node);
273
202
  }
274
- export function contains(node, offset, includeRightBound) {
275
- if (includeRightBound === void 0) { includeRightBound = false; }
203
+ export function contains(node, offset, includeRightBound = false) {
276
204
  return offset >= node.offset && offset < (node.offset + node.length) || includeRightBound && offset === (node.offset + node.length);
277
205
  }
278
- var JSONDocument = /** @class */ (function () {
279
- function JSONDocument(root, syntaxErrors, comments) {
280
- if (syntaxErrors === void 0) { syntaxErrors = []; }
281
- if (comments === void 0) { comments = []; }
206
+ export class JSONDocument {
207
+ constructor(root, syntaxErrors = [], comments = []) {
282
208
  this.root = root;
283
209
  this.syntaxErrors = syntaxErrors;
284
210
  this.comments = comments;
285
211
  }
286
- JSONDocument.prototype.getNodeFromOffset = function (offset, includeRightBound) {
287
- if (includeRightBound === void 0) { includeRightBound = false; }
212
+ getNodeFromOffset(offset, includeRightBound = false) {
288
213
  if (this.root) {
289
214
  return Json.findNodeAtOffset(this.root, offset, includeRightBound);
290
215
  }
291
216
  return undefined;
292
- };
293
- JSONDocument.prototype.visit = function (visitor) {
217
+ }
218
+ visit(visitor) {
294
219
  if (this.root) {
295
- var doVisit_1 = function (node) {
296
- var ctn = visitor(node);
297
- var children = node.children;
220
+ const doVisit = (node) => {
221
+ let ctn = visitor(node);
222
+ const children = node.children;
298
223
  if (Array.isArray(children)) {
299
- for (var i = 0; i < children.length && ctn; i++) {
300
- ctn = doVisit_1(children[i]);
224
+ for (let i = 0; i < children.length && ctn; i++) {
225
+ ctn = doVisit(children[i]);
301
226
  }
302
227
  }
303
228
  return ctn;
304
229
  };
305
- doVisit_1(this.root);
230
+ doVisit(this.root);
306
231
  }
307
- };
308
- JSONDocument.prototype.validate = function (textDocument, schema, severity) {
309
- if (severity === void 0) { severity = DiagnosticSeverity.Warning; }
232
+ }
233
+ validate(textDocument, schema, severity = DiagnosticSeverity.Warning) {
310
234
  if (this.root && schema) {
311
- var validationResult = new ValidationResult();
235
+ const validationResult = new ValidationResult();
312
236
  validate(this.root, schema, validationResult, NoOpSchemaCollector.instance);
313
- return validationResult.problems.map(function (p) {
314
- var _a;
315
- var range = Range.create(textDocument.positionAt(p.location.offset), textDocument.positionAt(p.location.offset + p.location.length));
316
- return Diagnostic.create(range, p.message, (_a = p.severity) !== null && _a !== void 0 ? _a : severity, p.code);
237
+ return validationResult.problems.map(p => {
238
+ const range = Range.create(textDocument.positionAt(p.location.offset), textDocument.positionAt(p.location.offset + p.location.length));
239
+ return Diagnostic.create(range, p.message, p.severity ?? severity, p.code);
317
240
  });
318
241
  }
319
242
  return undefined;
320
- };
321
- JSONDocument.prototype.getMatchingSchemas = function (schema, focusOffset, exclude) {
322
- if (focusOffset === void 0) { focusOffset = -1; }
323
- var matchingSchemas = new SchemaCollector(focusOffset, exclude);
243
+ }
244
+ getMatchingSchemas(schema, focusOffset = -1, exclude) {
245
+ const matchingSchemas = new SchemaCollector(focusOffset, exclude);
324
246
  if (this.root && schema) {
325
247
  validate(this.root, schema, new ValidationResult(), matchingSchemas);
326
248
  }
327
249
  return matchingSchemas.schemas;
328
- };
329
- return JSONDocument;
330
- }());
331
- export { JSONDocument };
250
+ }
251
+ }
332
252
  function validate(n, schema, validationResult, matchingSchemas) {
333
253
  if (!n || !matchingSchemas.include(n)) {
334
254
  return;
335
255
  }
336
- var node = n;
256
+ if (n.type === 'property') {
257
+ return validate(n.valueNode, schema, validationResult, matchingSchemas);
258
+ }
259
+ const node = n;
260
+ _validateNode();
337
261
  switch (node.type) {
338
262
  case 'object':
339
- _validateObjectNode(node, schema, validationResult, matchingSchemas);
263
+ _validateObjectNode(node);
340
264
  break;
341
265
  case 'array':
342
- _validateArrayNode(node, schema, validationResult, matchingSchemas);
266
+ _validateArrayNode(node);
343
267
  break;
344
268
  case 'string':
345
- _validateStringNode(node, schema, validationResult, matchingSchemas);
269
+ _validateStringNode(node);
346
270
  break;
347
271
  case 'number':
348
- _validateNumberNode(node, schema, validationResult, matchingSchemas);
272
+ _validateNumberNode(node);
349
273
  break;
350
- case 'property':
351
- return validate(node.valueNode, schema, validationResult, matchingSchemas);
352
274
  }
353
- _validateNode();
354
275
  matchingSchemas.add({ node: node, schema: schema });
355
276
  function _validateNode() {
356
277
  function matchesType(type) {
@@ -373,15 +294,14 @@ function validate(n, schema, validationResult, matchingSchemas) {
373
294
  }
374
295
  }
375
296
  if (Array.isArray(schema.allOf)) {
376
- for (var _i = 0, _a = schema.allOf; _i < _a.length; _i++) {
377
- var subSchemaRef = _a[_i];
297
+ for (const subSchemaRef of schema.allOf) {
378
298
  validate(node, asSchema(subSchemaRef), validationResult, matchingSchemas);
379
299
  }
380
300
  }
381
- var notSchema = asSchema(schema.not);
301
+ const notSchema = asSchema(schema.not);
382
302
  if (notSchema) {
383
- var subValidationResult = new ValidationResult();
384
- var subMatchingSchemas = matchingSchemas.newSub();
303
+ const subValidationResult = new ValidationResult();
304
+ const subMatchingSchemas = matchingSchemas.newSub();
385
305
  validate(node, notSchema, subValidationResult, subMatchingSchemas);
386
306
  if (!subValidationResult.hasProblems()) {
387
307
  validationResult.problems.push({
@@ -389,21 +309,19 @@ function validate(n, schema, validationResult, matchingSchemas) {
389
309
  message: localize('notSchemaWarning', "Matches a schema that is not allowed.")
390
310
  });
391
311
  }
392
- for (var _b = 0, _c = subMatchingSchemas.schemas; _b < _c.length; _b++) {
393
- var ms = _c[_b];
312
+ for (const ms of subMatchingSchemas.schemas) {
394
313
  ms.inverted = !ms.inverted;
395
314
  matchingSchemas.add(ms);
396
315
  }
397
316
  }
398
- var testAlternatives = function (alternatives, maxOneMatch) {
399
- var matches = [];
317
+ const testAlternatives = (alternatives, maxOneMatch) => {
318
+ const matches = [];
400
319
  // remember the best match that is used for error messages
401
- var bestMatch = undefined;
402
- for (var _i = 0, alternatives_1 = alternatives; _i < alternatives_1.length; _i++) {
403
- var subSchemaRef = alternatives_1[_i];
404
- var subSchema = asSchema(subSchemaRef);
405
- var subValidationResult = new ValidationResult();
406
- var subMatchingSchemas = matchingSchemas.newSub();
320
+ let bestMatch = undefined;
321
+ for (const subSchemaRef of alternatives) {
322
+ const subSchema = asSchema(subSchemaRef);
323
+ const subValidationResult = new ValidationResult();
324
+ const subMatchingSchemas = matchingSchemas.newSub();
407
325
  validate(node, subSchema, subValidationResult, subMatchingSchemas);
408
326
  if (!subValidationResult.hasProblems()) {
409
327
  matches.push(subSchema);
@@ -417,9 +335,10 @@ function validate(n, schema, validationResult, matchingSchemas) {
417
335
  bestMatch.matchingSchemas.merge(subMatchingSchemas);
418
336
  bestMatch.validationResult.propertiesMatches += subValidationResult.propertiesMatches;
419
337
  bestMatch.validationResult.propertiesValueMatches += subValidationResult.propertiesValueMatches;
338
+ bestMatch.validationResult.mergeProcessedProperties(subValidationResult);
420
339
  }
421
340
  else {
422
- var compareResult = subValidationResult.compare(bestMatch.validationResult);
341
+ const compareResult = subValidationResult.compare(bestMatch.validationResult);
423
342
  if (compareResult > 0) {
424
343
  // our node is the best matching so far
425
344
  bestMatch = { schema: subSchema, validationResult: subValidationResult, matchingSchemas: subMatchingSchemas };
@@ -442,6 +361,7 @@ function validate(n, schema, validationResult, matchingSchemas) {
442
361
  validationResult.merge(bestMatch.validationResult);
443
362
  validationResult.propertiesMatches += bestMatch.validationResult.propertiesMatches;
444
363
  validationResult.propertiesValueMatches += bestMatch.validationResult.propertiesValueMatches;
364
+ validationResult.mergeProcessedProperties(bestMatch.validationResult);
445
365
  matchingSchemas.merge(bestMatch.matchingSchemas);
446
366
  }
447
367
  return matches.length;
@@ -452,21 +372,23 @@ function validate(n, schema, validationResult, matchingSchemas) {
452
372
  if (Array.isArray(schema.oneOf)) {
453
373
  testAlternatives(schema.oneOf, true);
454
374
  }
455
- var testBranch = function (schema) {
456
- var subValidationResult = new ValidationResult();
457
- var subMatchingSchemas = matchingSchemas.newSub();
375
+ const testBranch = (schema) => {
376
+ const subValidationResult = new ValidationResult();
377
+ const subMatchingSchemas = matchingSchemas.newSub();
458
378
  validate(node, asSchema(schema), subValidationResult, subMatchingSchemas);
459
379
  validationResult.merge(subValidationResult);
460
380
  validationResult.propertiesMatches += subValidationResult.propertiesMatches;
461
381
  validationResult.propertiesValueMatches += subValidationResult.propertiesValueMatches;
382
+ validationResult.mergeProcessedProperties(subValidationResult);
462
383
  matchingSchemas.merge(subMatchingSchemas);
463
384
  };
464
- var testCondition = function (ifSchema, thenSchema, elseSchema) {
465
- var subSchema = asSchema(ifSchema);
466
- var subValidationResult = new ValidationResult();
467
- var subMatchingSchemas = matchingSchemas.newSub();
385
+ const testCondition = (ifSchema, thenSchema, elseSchema) => {
386
+ const subSchema = asSchema(ifSchema);
387
+ const subValidationResult = new ValidationResult();
388
+ const subMatchingSchemas = matchingSchemas.newSub();
468
389
  validate(node, subSchema, subValidationResult, subMatchingSchemas);
469
390
  matchingSchemas.merge(subMatchingSchemas);
391
+ validationResult.mergeProcessedProperties(subValidationResult);
470
392
  if (!subValidationResult.hasProblems()) {
471
393
  if (thenSchema) {
472
394
  testBranch(thenSchema);
@@ -476,15 +398,14 @@ function validate(n, schema, validationResult, matchingSchemas) {
476
398
  testBranch(elseSchema);
477
399
  }
478
400
  };
479
- var ifSchema = asSchema(schema.if);
401
+ const ifSchema = asSchema(schema.if);
480
402
  if (ifSchema) {
481
403
  testCondition(ifSchema, asSchema(schema.then), asSchema(schema.else));
482
404
  }
483
405
  if (Array.isArray(schema.enum)) {
484
- var val = getNodeValue(node);
485
- var enumValueMatch = false;
486
- for (var _d = 0, _e = schema.enum; _d < _e.length; _d++) {
487
- var e = _e[_d];
406
+ const val = getNodeValue(node);
407
+ let enumValueMatch = false;
408
+ for (const e of schema.enum) {
488
409
  if (equals(val, e)) {
489
410
  enumValueMatch = true;
490
411
  break;
@@ -496,12 +417,12 @@ function validate(n, schema, validationResult, matchingSchemas) {
496
417
  validationResult.problems.push({
497
418
  location: { offset: node.offset, length: node.length },
498
419
  code: ErrorCode.EnumValueMismatch,
499
- message: schema.errorMessage || localize('enumWarning', 'Value is not accepted. Valid values: {0}.', schema.enum.map(function (v) { return JSON.stringify(v); }).join(', '))
420
+ message: schema.errorMessage || localize('enumWarning', 'Value is not accepted. Valid values: {0}.', schema.enum.map(v => JSON.stringify(v)).join(', '))
500
421
  });
501
422
  }
502
423
  }
503
424
  if (isDefined(schema.const)) {
504
- var val = getNodeValue(node);
425
+ const val = getNodeValue(node);
505
426
  if (!equals(val, schema.const)) {
506
427
  validationResult.problems.push({
507
428
  location: { offset: node.offset, length: node.length },
@@ -515,36 +436,37 @@ function validate(n, schema, validationResult, matchingSchemas) {
515
436
  }
516
437
  validationResult.enumValues = [schema.const];
517
438
  }
518
- if (schema.deprecationMessage && node.parent) {
439
+ let deprecationMessage = schema.deprecationMessage;
440
+ if ((deprecationMessage || schema.deprecated) && node.parent) {
441
+ deprecationMessage = deprecationMessage || localize('deprecated', 'Value is deprecated');
519
442
  validationResult.problems.push({
520
443
  location: { offset: node.parent.offset, length: node.parent.length },
521
444
  severity: DiagnosticSeverity.Warning,
522
- message: schema.deprecationMessage,
445
+ message: deprecationMessage,
523
446
  code: ErrorCode.Deprecated
524
447
  });
525
448
  }
526
449
  }
527
- function _validateNumberNode(node, schema, validationResult, matchingSchemas) {
528
- var val = node.value;
450
+ function _validateNumberNode(node) {
451
+ const val = node.value;
529
452
  function normalizeFloats(float) {
530
- var _a;
531
- var parts = /^(-?\d+)(?:\.(\d+))?(?:e([-+]\d+))?$/.exec(float.toString());
453
+ const parts = /^(-?\d+)(?:\.(\d+))?(?:e([-+]\d+))?$/.exec(float.toString());
532
454
  return parts && {
533
455
  value: Number(parts[1] + (parts[2] || '')),
534
- multiplier: (((_a = parts[2]) === null || _a === void 0 ? void 0 : _a.length) || 0) - (parseInt(parts[3]) || 0)
456
+ multiplier: (parts[2]?.length || 0) - (parseInt(parts[3]) || 0)
535
457
  };
536
458
  }
537
459
  ;
538
460
  if (isNumber(schema.multipleOf)) {
539
- var remainder = -1;
461
+ let remainder = -1;
540
462
  if (Number.isInteger(schema.multipleOf)) {
541
463
  remainder = val % schema.multipleOf;
542
464
  }
543
465
  else {
544
- var normMultipleOf = normalizeFloats(schema.multipleOf);
545
- var normValue = normalizeFloats(val);
466
+ let normMultipleOf = normalizeFloats(schema.multipleOf);
467
+ let normValue = normalizeFloats(val);
546
468
  if (normMultipleOf && normValue) {
547
- var multiplier = Math.pow(10, Math.abs(normValue.multiplier - normMultipleOf.multiplier));
469
+ const multiplier = 10 ** Math.abs(normValue.multiplier - normMultipleOf.multiplier);
548
470
  if (normValue.multiplier < normMultipleOf.multiplier) {
549
471
  normValue.value *= multiplier;
550
472
  }
@@ -576,28 +498,28 @@ function validate(n, schema, validationResult, matchingSchemas) {
576
498
  }
577
499
  return undefined;
578
500
  }
579
- var exclusiveMinimum = getExclusiveLimit(schema.minimum, schema.exclusiveMinimum);
501
+ const exclusiveMinimum = getExclusiveLimit(schema.minimum, schema.exclusiveMinimum);
580
502
  if (isNumber(exclusiveMinimum) && val <= exclusiveMinimum) {
581
503
  validationResult.problems.push({
582
504
  location: { offset: node.offset, length: node.length },
583
505
  message: localize('exclusiveMinimumWarning', 'Value is below the exclusive minimum of {0}.', exclusiveMinimum)
584
506
  });
585
507
  }
586
- var exclusiveMaximum = getExclusiveLimit(schema.maximum, schema.exclusiveMaximum);
508
+ const exclusiveMaximum = getExclusiveLimit(schema.maximum, schema.exclusiveMaximum);
587
509
  if (isNumber(exclusiveMaximum) && val >= exclusiveMaximum) {
588
510
  validationResult.problems.push({
589
511
  location: { offset: node.offset, length: node.length },
590
512
  message: localize('exclusiveMaximumWarning', 'Value is above the exclusive maximum of {0}.', exclusiveMaximum)
591
513
  });
592
514
  }
593
- var minimum = getLimit(schema.minimum, schema.exclusiveMinimum);
515
+ const minimum = getLimit(schema.minimum, schema.exclusiveMinimum);
594
516
  if (isNumber(minimum) && val < minimum) {
595
517
  validationResult.problems.push({
596
518
  location: { offset: node.offset, length: node.length },
597
519
  message: localize('minimumWarning', 'Value is below the minimum of {0}.', minimum)
598
520
  });
599
521
  }
600
- var maximum = getLimit(schema.maximum, schema.exclusiveMaximum);
522
+ const maximum = getLimit(schema.maximum, schema.exclusiveMaximum);
601
523
  if (isNumber(maximum) && val > maximum) {
602
524
  validationResult.problems.push({
603
525
  location: { offset: node.offset, length: node.length },
@@ -605,7 +527,7 @@ function validate(n, schema, validationResult, matchingSchemas) {
605
527
  });
606
528
  }
607
529
  }
608
- function _validateStringNode(node, schema, validationResult, matchingSchemas) {
530
+ function _validateStringNode(node) {
609
531
  if (isNumber(schema.minLength) && node.value.length < schema.minLength) {
610
532
  validationResult.problems.push({
611
533
  location: { offset: node.offset, length: node.length },
@@ -619,8 +541,8 @@ function validate(n, schema, validationResult, matchingSchemas) {
619
541
  });
620
542
  }
621
543
  if (isString(schema.pattern)) {
622
- var regex = extendedRegExp(schema.pattern);
623
- if (!(regex === null || regex === void 0 ? void 0 : regex.test(node.value))) {
544
+ const regex = extendedRegExp(schema.pattern);
545
+ if (!(regex?.test(node.value))) {
624
546
  validationResult.problems.push({
625
547
  location: { offset: node.offset, length: node.length },
626
548
  message: schema.patternErrorMessage || schema.errorMessage || localize('patternWarning', 'String does not match the pattern of "{0}".', schema.pattern)
@@ -632,12 +554,12 @@ function validate(n, schema, validationResult, matchingSchemas) {
632
554
  case 'uri':
633
555
  case 'uri-reference':
634
556
  {
635
- var errorMessage = void 0;
557
+ let errorMessage;
636
558
  if (!node.value) {
637
559
  errorMessage = localize('uriEmpty', 'URI expected.');
638
560
  }
639
561
  else {
640
- var match = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/.exec(node.value);
562
+ const match = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/.exec(node.value);
641
563
  if (!match) {
642
564
  errorMessage = localize('uriMissing', 'URI is expected.');
643
565
  }
@@ -661,7 +583,7 @@ function validate(n, schema, validationResult, matchingSchemas) {
661
583
  case 'hostname':
662
584
  case 'ipv4':
663
585
  case 'ipv6':
664
- var format = formats[schema.format];
586
+ const format = formats[schema.format];
665
587
  if (!node.value || !format.pattern.exec(node.value)) {
666
588
  validationResult.problems.push({
667
589
  location: { offset: node.offset, length: node.length },
@@ -672,62 +594,107 @@ function validate(n, schema, validationResult, matchingSchemas) {
672
594
  }
673
595
  }
674
596
  }
675
- function _validateArrayNode(node, schema, validationResult, matchingSchemas) {
676
- if (Array.isArray(schema.items)) {
677
- var subSchemas = schema.items;
678
- for (var index = 0; index < subSchemas.length; index++) {
679
- var subSchemaRef = subSchemas[index];
680
- var subSchema = asSchema(subSchemaRef);
681
- var itemValidationResult = new ValidationResult();
682
- var item = node.items[index];
597
+ function _validateArrayNode(node) {
598
+ let prefixItemsSchemas;
599
+ let additionalItemSchema;
600
+ let isSchema_2020_12 = Array.isArray(schema.prefixItems) || (schema.items !== undefined && !Array.isArray(schema.items) && schema.additionalItems === undefined);
601
+ if (isSchema_2020_12) {
602
+ prefixItemsSchemas = schema.prefixItems;
603
+ additionalItemSchema = !Array.isArray(schema.items) ? schema.items : undefined;
604
+ }
605
+ else {
606
+ prefixItemsSchemas = Array.isArray(schema.items) ? schema.items : undefined;
607
+ additionalItemSchema = !Array.isArray(schema.items) ? schema.items : schema.additionalItems;
608
+ }
609
+ let index = 0;
610
+ if (prefixItemsSchemas !== undefined) {
611
+ const max = Math.min(prefixItemsSchemas.length, node.items.length);
612
+ for (; index < max; index++) {
613
+ const subSchemaRef = prefixItemsSchemas[index];
614
+ const subSchema = asSchema(subSchemaRef);
615
+ const itemValidationResult = new ValidationResult();
616
+ const item = node.items[index];
683
617
  if (item) {
684
618
  validate(item, subSchema, itemValidationResult, matchingSchemas);
685
619
  validationResult.mergePropertyMatch(itemValidationResult);
686
620
  }
687
- else if (node.items.length >= subSchemas.length) {
688
- validationResult.propertiesValueMatches++;
689
- }
621
+ validationResult.processedProperties.add(String(index));
690
622
  }
691
- if (node.items.length > subSchemas.length) {
692
- if (typeof schema.additionalItems === 'object') {
693
- for (var i = subSchemas.length; i < node.items.length; i++) {
694
- var itemValidationResult = new ValidationResult();
695
- validate(node.items[i], schema.additionalItems, itemValidationResult, matchingSchemas);
696
- validationResult.mergePropertyMatch(itemValidationResult);
697
- }
698
- }
699
- else if (schema.additionalItems === false) {
623
+ }
624
+ if (additionalItemSchema !== undefined && index < node.items.length) {
625
+ if (typeof additionalItemSchema === 'boolean') {
626
+ if (additionalItemSchema === false) {
700
627
  validationResult.problems.push({
701
628
  location: { offset: node.offset, length: node.length },
702
- message: localize('additionalItemsWarning', 'Array has too many items according to schema. Expected {0} or fewer.', subSchemas.length)
629
+ message: localize('additionalItemsWarning', 'Array has too many items according to schema. Expected {0} or fewer.', index)
703
630
  });
704
631
  }
632
+ for (; index < node.items.length; index++) {
633
+ validationResult.processedProperties.add(String(index));
634
+ validationResult.propertiesValueMatches++;
635
+ }
705
636
  }
706
- }
707
- else {
708
- var itemSchema = asSchema(schema.items);
709
- if (itemSchema) {
710
- for (var _i = 0, _a = node.items; _i < _a.length; _i++) {
711
- var item = _a[_i];
712
- var itemValidationResult = new ValidationResult();
713
- validate(item, itemSchema, itemValidationResult, matchingSchemas);
637
+ else {
638
+ for (; index < node.items.length; index++) {
639
+ const itemValidationResult = new ValidationResult();
640
+ validate(node.items[index], additionalItemSchema, itemValidationResult, matchingSchemas);
714
641
  validationResult.mergePropertyMatch(itemValidationResult);
642
+ validationResult.processedProperties.add(String(index));
715
643
  }
716
644
  }
717
645
  }
718
- var containsSchema = asSchema(schema.contains);
646
+ const containsSchema = asSchema(schema.contains);
719
647
  if (containsSchema) {
720
- var doesContain = node.items.some(function (item) {
721
- var itemValidationResult = new ValidationResult();
648
+ let containsCount = 0;
649
+ for (let index = 0; index < node.items.length; index++) {
650
+ const item = node.items[index];
651
+ const itemValidationResult = new ValidationResult();
722
652
  validate(item, containsSchema, itemValidationResult, NoOpSchemaCollector.instance);
723
- return !itemValidationResult.hasProblems();
724
- });
725
- if (!doesContain) {
653
+ if (!itemValidationResult.hasProblems()) {
654
+ containsCount++;
655
+ if (isSchema_2020_12) {
656
+ validationResult.processedProperties.add(String(index));
657
+ }
658
+ }
659
+ }
660
+ if (containsCount === 0 && !isNumber(schema.minContains)) {
726
661
  validationResult.problems.push({
727
662
  location: { offset: node.offset, length: node.length },
728
663
  message: schema.errorMessage || localize('requiredItemMissingWarning', 'Array does not contain required item.')
729
664
  });
730
665
  }
666
+ if (isNumber(schema.minContains) && containsCount < schema.minContains) {
667
+ validationResult.problems.push({
668
+ location: { offset: node.offset, length: node.length },
669
+ message: localize('minContainsWarning', 'Array has too few items that match the contains contraint. Expected {0} or more.', schema.minContains)
670
+ });
671
+ }
672
+ if (isNumber(schema.maxContains) && containsCount > schema.maxContains) {
673
+ validationResult.problems.push({
674
+ location: { offset: node.offset, length: node.length },
675
+ message: localize('maxContainsWarning', 'Array has too many items that match the contains contraint. Expected {0} or less.', schema.maxContains)
676
+ });
677
+ }
678
+ }
679
+ const unevaluatedItems = schema.unevaluatedItems;
680
+ if (unevaluatedItems !== undefined) {
681
+ for (let i = 0; i < node.items.length; i++) {
682
+ if (!validationResult.processedProperties.has(String(i))) {
683
+ if (unevaluatedItems === false) {
684
+ validationResult.problems.push({
685
+ location: { offset: node.offset, length: node.length },
686
+ message: localize('unevaluatedItemsWarning', 'Item does not match any validation rule from the array.')
687
+ });
688
+ }
689
+ else {
690
+ const itemValidationResult = new ValidationResult();
691
+ validate(node.items[i], schema.additionalItems, itemValidationResult, matchingSchemas);
692
+ validationResult.mergePropertyMatch(itemValidationResult);
693
+ }
694
+ }
695
+ validationResult.processedProperties.add(String(i));
696
+ validationResult.propertiesValueMatches++;
697
+ }
731
698
  }
732
699
  if (isNumber(schema.minItems) && node.items.length < schema.minItems) {
733
700
  validationResult.problems.push({
@@ -742,9 +709,9 @@ function validate(n, schema, validationResult, matchingSchemas) {
742
709
  });
743
710
  }
744
711
  if (schema.uniqueItems === true) {
745
- var values_1 = getNodeValue(node);
746
- var duplicates = values_1.some(function (value, index) {
747
- return index !== values_1.lastIndexOf(value);
712
+ const values = getNodeValue(node);
713
+ const duplicates = values.some((value, index) => {
714
+ return index !== values.lastIndexOf(value);
748
715
  });
749
716
  if (duplicates) {
750
717
  validationResult.problems.push({
@@ -754,21 +721,19 @@ function validate(n, schema, validationResult, matchingSchemas) {
754
721
  }
755
722
  }
756
723
  }
757
- function _validateObjectNode(node, schema, validationResult, matchingSchemas) {
758
- var seenKeys = Object.create(null);
759
- var unprocessedProperties = [];
760
- for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
761
- var propertyNode = _a[_i];
762
- var key = propertyNode.keyNode.value;
724
+ function _validateObjectNode(node) {
725
+ const seenKeys = Object.create(null);
726
+ const unprocessedProperties = new Set();
727
+ for (const propertyNode of node.properties) {
728
+ const key = propertyNode.keyNode.value;
763
729
  seenKeys[key] = propertyNode.valueNode;
764
- unprocessedProperties.push(key);
730
+ unprocessedProperties.add(key);
765
731
  }
766
732
  if (Array.isArray(schema.required)) {
767
- for (var _b = 0, _c = schema.required; _b < _c.length; _b++) {
768
- var propertyName = _c[_b];
733
+ for (const propertyName of schema.required) {
769
734
  if (!seenKeys[propertyName]) {
770
- var keyNode = node.parent && node.parent.type === 'property' && node.parent.keyNode;
771
- var location = keyNode ? { offset: keyNode.offset, length: keyNode.length } : { offset: node.offset, length: 1 };
735
+ const keyNode = node.parent && node.parent.type === 'property' && node.parent.keyNode;
736
+ const location = keyNode ? { offset: keyNode.offset, length: keyNode.length } : { offset: node.offset, length: 1 };
772
737
  validationResult.problems.push({
773
738
  location: location,
774
739
  message: localize('MissingRequiredPropWarning', 'Missing property "{0}".', propertyName)
@@ -776,23 +741,19 @@ function validate(n, schema, validationResult, matchingSchemas) {
776
741
  }
777
742
  }
778
743
  }
779
- var propertyProcessed = function (prop) {
780
- var index = unprocessedProperties.indexOf(prop);
781
- while (index >= 0) {
782
- unprocessedProperties.splice(index, 1);
783
- index = unprocessedProperties.indexOf(prop);
784
- }
744
+ const propertyProcessed = (prop) => {
745
+ unprocessedProperties.delete(prop);
746
+ validationResult.processedProperties.add(prop);
785
747
  };
786
748
  if (schema.properties) {
787
- for (var _d = 0, _e = Object.keys(schema.properties); _d < _e.length; _d++) {
788
- var propertyName = _e[_d];
749
+ for (const propertyName of Object.keys(schema.properties)) {
789
750
  propertyProcessed(propertyName);
790
- var propertySchema = schema.properties[propertyName];
791
- var child = seenKeys[propertyName];
751
+ const propertySchema = schema.properties[propertyName];
752
+ const child = seenKeys[propertyName];
792
753
  if (child) {
793
754
  if (isBoolean(propertySchema)) {
794
755
  if (!propertySchema) {
795
- var propertyNode = child.parent;
756
+ const propertyNode = child.parent;
796
757
  validationResult.problems.push({
797
758
  location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
798
759
  message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
@@ -804,7 +765,7 @@ function validate(n, schema, validationResult, matchingSchemas) {
804
765
  }
805
766
  }
806
767
  else {
807
- var propertyValidationResult = new ValidationResult();
768
+ const propertyValidationResult = new ValidationResult();
808
769
  validate(child, propertySchema, propertyValidationResult, matchingSchemas);
809
770
  validationResult.mergePropertyMatch(propertyValidationResult);
810
771
  }
@@ -812,64 +773,86 @@ function validate(n, schema, validationResult, matchingSchemas) {
812
773
  }
813
774
  }
814
775
  if (schema.patternProperties) {
815
- for (var _f = 0, _g = Object.keys(schema.patternProperties); _f < _g.length; _f++) {
816
- var propertyPattern = _g[_f];
817
- var regex = extendedRegExp(propertyPattern);
818
- for (var _h = 0, _j = unprocessedProperties.slice(0); _h < _j.length; _h++) {
819
- var propertyName = _j[_h];
820
- if (regex === null || regex === void 0 ? void 0 : regex.test(propertyName)) {
821
- propertyProcessed(propertyName);
822
- var child = seenKeys[propertyName];
823
- if (child) {
824
- var propertySchema = schema.patternProperties[propertyPattern];
825
- if (isBoolean(propertySchema)) {
826
- if (!propertySchema) {
827
- var propertyNode = child.parent;
828
- validationResult.problems.push({
829
- location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
830
- message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
831
- });
776
+ for (const propertyPattern of Object.keys(schema.patternProperties)) {
777
+ const regex = extendedRegExp(propertyPattern);
778
+ if (regex) {
779
+ const processed = [];
780
+ for (const propertyName of unprocessedProperties) {
781
+ if (regex.test(propertyName)) {
782
+ processed.push(propertyName);
783
+ const child = seenKeys[propertyName];
784
+ if (child) {
785
+ const propertySchema = schema.patternProperties[propertyPattern];
786
+ if (isBoolean(propertySchema)) {
787
+ if (!propertySchema) {
788
+ const propertyNode = child.parent;
789
+ validationResult.problems.push({
790
+ location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
791
+ message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
792
+ });
793
+ }
794
+ else {
795
+ validationResult.propertiesMatches++;
796
+ validationResult.propertiesValueMatches++;
797
+ }
832
798
  }
833
799
  else {
834
- validationResult.propertiesMatches++;
835
- validationResult.propertiesValueMatches++;
800
+ const propertyValidationResult = new ValidationResult();
801
+ validate(child, propertySchema, propertyValidationResult, matchingSchemas);
802
+ validationResult.mergePropertyMatch(propertyValidationResult);
836
803
  }
837
804
  }
838
- else {
839
- var propertyValidationResult = new ValidationResult();
840
- validate(child, propertySchema, propertyValidationResult, matchingSchemas);
841
- validationResult.mergePropertyMatch(propertyValidationResult);
842
- }
843
805
  }
844
806
  }
807
+ processed.forEach(propertyProcessed);
845
808
  }
846
809
  }
847
810
  }
848
- if (typeof schema.additionalProperties === 'object') {
849
- for (var _k = 0, unprocessedProperties_1 = unprocessedProperties; _k < unprocessedProperties_1.length; _k++) {
850
- var propertyName = unprocessedProperties_1[_k];
851
- var child = seenKeys[propertyName];
811
+ const additionalProperties = schema.additionalProperties;
812
+ if (additionalProperties !== undefined && additionalProperties !== true) {
813
+ for (const propertyName of unprocessedProperties) {
814
+ propertyProcessed(propertyName);
815
+ const child = seenKeys[propertyName];
852
816
  if (child) {
853
- var propertyValidationResult = new ValidationResult();
854
- validate(child, schema.additionalProperties, propertyValidationResult, matchingSchemas);
855
- validationResult.mergePropertyMatch(propertyValidationResult);
856
- }
857
- }
858
- }
859
- else if (schema.additionalProperties === false) {
860
- if (unprocessedProperties.length > 0) {
861
- for (var _l = 0, unprocessedProperties_2 = unprocessedProperties; _l < unprocessedProperties_2.length; _l++) {
862
- var propertyName = unprocessedProperties_2[_l];
863
- var child = seenKeys[propertyName];
864
- if (child) {
865
- var propertyNode = child.parent;
817
+ if (additionalProperties === false) {
818
+ const propertyNode = child.parent;
866
819
  validationResult.problems.push({
867
820
  location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
868
821
  message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
869
822
  });
870
823
  }
824
+ else {
825
+ const propertyValidationResult = new ValidationResult();
826
+ validate(child, additionalProperties, propertyValidationResult, matchingSchemas);
827
+ validationResult.mergePropertyMatch(propertyValidationResult);
828
+ }
829
+ }
830
+ }
831
+ }
832
+ const unevaluatedProperties = schema.unevaluatedProperties;
833
+ if (unevaluatedProperties !== undefined && unevaluatedProperties !== true) {
834
+ const processed = [];
835
+ for (const propertyName of unprocessedProperties) {
836
+ if (!validationResult.processedProperties.has(propertyName)) {
837
+ processed.push(propertyName);
838
+ const child = seenKeys[propertyName];
839
+ if (child) {
840
+ if (unevaluatedProperties === false) {
841
+ const propertyNode = child.parent;
842
+ validationResult.problems.push({
843
+ location: { offset: propertyNode.keyNode.offset, length: propertyNode.keyNode.length },
844
+ message: schema.errorMessage || localize('DisallowedExtraPropWarning', 'Property {0} is not allowed.', propertyName)
845
+ });
846
+ }
847
+ else {
848
+ const propertyValidationResult = new ValidationResult();
849
+ validate(child, unevaluatedProperties, propertyValidationResult, matchingSchemas);
850
+ validationResult.mergePropertyMatch(propertyValidationResult);
851
+ }
852
+ }
871
853
  }
872
854
  }
855
+ processed.forEach(propertyProcessed);
873
856
  }
874
857
  if (isNumber(schema.maxProperties)) {
875
858
  if (node.properties.length > schema.maxProperties) {
@@ -887,71 +870,88 @@ function validate(n, schema, validationResult, matchingSchemas) {
887
870
  });
888
871
  }
889
872
  }
873
+ if (schema.dependentRequired) {
874
+ for (const key in schema.dependentRequired) {
875
+ const prop = seenKeys[key];
876
+ const propertyDeps = schema.dependentRequired[key];
877
+ if (prop && Array.isArray(propertyDeps)) {
878
+ _validatePropertyDependencies(key, propertyDeps);
879
+ }
880
+ }
881
+ }
882
+ if (schema.dependentSchemas) {
883
+ for (const key in schema.dependentSchemas) {
884
+ const prop = seenKeys[key];
885
+ const propertyDeps = schema.dependentSchemas[key];
886
+ if (prop && isObject(propertyDeps)) {
887
+ _validatePropertyDependencies(key, propertyDeps);
888
+ }
889
+ }
890
+ }
890
891
  if (schema.dependencies) {
891
- for (var _m = 0, _o = Object.keys(schema.dependencies); _m < _o.length; _m++) {
892
- var key = _o[_m];
893
- var prop = seenKeys[key];
892
+ for (const key in schema.dependencies) {
893
+ const prop = seenKeys[key];
894
894
  if (prop) {
895
- var propertyDep = schema.dependencies[key];
896
- if (Array.isArray(propertyDep)) {
897
- for (var _p = 0, propertyDep_1 = propertyDep; _p < propertyDep_1.length; _p++) {
898
- var requiredProp = propertyDep_1[_p];
899
- if (!seenKeys[requiredProp]) {
900
- validationResult.problems.push({
901
- location: { offset: node.offset, length: node.length },
902
- message: localize('RequiredDependentPropWarning', 'Object is missing property {0} required by property {1}.', requiredProp, key)
903
- });
904
- }
905
- else {
906
- validationResult.propertiesValueMatches++;
907
- }
908
- }
909
- }
910
- else {
911
- var propertySchema = asSchema(propertyDep);
912
- if (propertySchema) {
913
- var propertyValidationResult = new ValidationResult();
914
- validate(node, propertySchema, propertyValidationResult, matchingSchemas);
915
- validationResult.mergePropertyMatch(propertyValidationResult);
916
- }
917
- }
895
+ _validatePropertyDependencies(key, schema.dependencies[key]);
918
896
  }
919
897
  }
920
898
  }
921
- var propertyNames = asSchema(schema.propertyNames);
899
+ const propertyNames = asSchema(schema.propertyNames);
922
900
  if (propertyNames) {
923
- for (var _q = 0, _r = node.properties; _q < _r.length; _q++) {
924
- var f = _r[_q];
925
- var key = f.keyNode;
901
+ for (const f of node.properties) {
902
+ const key = f.keyNode;
926
903
  if (key) {
927
904
  validate(key, propertyNames, validationResult, NoOpSchemaCollector.instance);
928
905
  }
929
906
  }
930
907
  }
908
+ function _validatePropertyDependencies(key, propertyDep) {
909
+ if (Array.isArray(propertyDep)) {
910
+ for (const requiredProp of propertyDep) {
911
+ if (!seenKeys[requiredProp]) {
912
+ validationResult.problems.push({
913
+ location: { offset: node.offset, length: node.length },
914
+ message: localize('RequiredDependentPropWarning', 'Object is missing property {0} required by property {1}.', requiredProp, key)
915
+ });
916
+ }
917
+ else {
918
+ validationResult.propertiesValueMatches++;
919
+ }
920
+ }
921
+ }
922
+ else {
923
+ const propertySchema = asSchema(propertyDep);
924
+ if (propertySchema) {
925
+ const propertyValidationResult = new ValidationResult();
926
+ validate(node, propertySchema, propertyValidationResult, matchingSchemas);
927
+ validationResult.mergePropertyMatch(propertyValidationResult);
928
+ }
929
+ }
930
+ }
931
931
  }
932
932
  }
933
933
  export function parse(textDocument, config) {
934
- var problems = [];
935
- var lastProblemOffset = -1;
936
- var text = textDocument.getText();
937
- var scanner = Json.createScanner(text, false);
938
- var commentRanges = config && config.collectComments ? [] : undefined;
934
+ const problems = [];
935
+ let lastProblemOffset = -1;
936
+ const text = textDocument.getText();
937
+ const scanner = Json.createScanner(text, false);
938
+ const commentRanges = config && config.collectComments ? [] : undefined;
939
939
  function _scanNext() {
940
940
  while (true) {
941
- var token_1 = scanner.scan();
941
+ const token = scanner.scan();
942
942
  _checkScanError();
943
- switch (token_1) {
944
- case 12 /* LineCommentTrivia */:
945
- case 13 /* BlockCommentTrivia */:
943
+ switch (token) {
944
+ case 12 /* Json.SyntaxKind.LineCommentTrivia */:
945
+ case 13 /* Json.SyntaxKind.BlockCommentTrivia */:
946
946
  if (Array.isArray(commentRanges)) {
947
947
  commentRanges.push(Range.create(textDocument.positionAt(scanner.getTokenOffset()), textDocument.positionAt(scanner.getTokenOffset() + scanner.getTokenLength())));
948
948
  }
949
949
  break;
950
- case 15 /* Trivia */:
951
- case 14 /* LineBreakTrivia */:
950
+ case 15 /* Json.SyntaxKind.Trivia */:
951
+ case 14 /* Json.SyntaxKind.LineBreakTrivia */:
952
952
  break;
953
953
  default:
954
- return token_1;
954
+ return token;
955
955
  }
956
956
  }
957
957
  }
@@ -962,20 +962,16 @@ export function parse(textDocument, config) {
962
962
  }
963
963
  return false;
964
964
  }
965
- function _errorAtRange(message, code, startOffset, endOffset, severity) {
966
- if (severity === void 0) { severity = DiagnosticSeverity.Error; }
965
+ function _errorAtRange(message, code, startOffset, endOffset, severity = DiagnosticSeverity.Error) {
967
966
  if (problems.length === 0 || startOffset !== lastProblemOffset) {
968
- var range = Range.create(textDocument.positionAt(startOffset), textDocument.positionAt(endOffset));
967
+ const range = Range.create(textDocument.positionAt(startOffset), textDocument.positionAt(endOffset));
969
968
  problems.push(Diagnostic.create(range, message, severity, code, textDocument.languageId));
970
969
  lastProblemOffset = startOffset;
971
970
  }
972
971
  }
973
- function _error(message, code, node, skipUntilAfter, skipUntil) {
974
- if (node === void 0) { node = undefined; }
975
- if (skipUntilAfter === void 0) { skipUntilAfter = []; }
976
- if (skipUntil === void 0) { skipUntil = []; }
977
- var start = scanner.getTokenOffset();
978
- var end = scanner.getTokenOffset() + scanner.getTokenLength();
972
+ function _error(message, code, node = undefined, skipUntilAfter = [], skipUntil = []) {
973
+ let start = scanner.getTokenOffset();
974
+ let end = scanner.getTokenOffset() + scanner.getTokenLength();
979
975
  if (start === end && start > 0) {
980
976
  start--;
981
977
  while (start > 0 && /\s/.test(text.charAt(start))) {
@@ -988,38 +984,38 @@ export function parse(textDocument, config) {
988
984
  _finalize(node, false);
989
985
  }
990
986
  if (skipUntilAfter.length + skipUntil.length > 0) {
991
- var token_2 = scanner.getToken();
992
- while (token_2 !== 17 /* EOF */) {
993
- if (skipUntilAfter.indexOf(token_2) !== -1) {
987
+ let token = scanner.getToken();
988
+ while (token !== 17 /* Json.SyntaxKind.EOF */) {
989
+ if (skipUntilAfter.indexOf(token) !== -1) {
994
990
  _scanNext();
995
991
  break;
996
992
  }
997
- else if (skipUntil.indexOf(token_2) !== -1) {
993
+ else if (skipUntil.indexOf(token) !== -1) {
998
994
  break;
999
995
  }
1000
- token_2 = _scanNext();
996
+ token = _scanNext();
1001
997
  }
1002
998
  }
1003
999
  return node;
1004
1000
  }
1005
1001
  function _checkScanError() {
1006
1002
  switch (scanner.getTokenError()) {
1007
- case 4 /* InvalidUnicode */:
1003
+ case 4 /* Json.ScanError.InvalidUnicode */:
1008
1004
  _error(localize('InvalidUnicode', 'Invalid unicode sequence in string.'), ErrorCode.InvalidUnicode);
1009
1005
  return true;
1010
- case 5 /* InvalidEscapeCharacter */:
1006
+ case 5 /* Json.ScanError.InvalidEscapeCharacter */:
1011
1007
  _error(localize('InvalidEscapeCharacter', 'Invalid escape character in string.'), ErrorCode.InvalidEscapeCharacter);
1012
1008
  return true;
1013
- case 3 /* UnexpectedEndOfNumber */:
1009
+ case 3 /* Json.ScanError.UnexpectedEndOfNumber */:
1014
1010
  _error(localize('UnexpectedEndOfNumber', 'Unexpected end of number.'), ErrorCode.UnexpectedEndOfNumber);
1015
1011
  return true;
1016
- case 1 /* UnexpectedEndOfComment */:
1012
+ case 1 /* Json.ScanError.UnexpectedEndOfComment */:
1017
1013
  _error(localize('UnexpectedEndOfComment', 'Unexpected end of comment.'), ErrorCode.UnexpectedEndOfComment);
1018
1014
  return true;
1019
- case 2 /* UnexpectedEndOfString */:
1015
+ case 2 /* Json.ScanError.UnexpectedEndOfString */:
1020
1016
  _error(localize('UnexpectedEndOfString', 'Unexpected end of string.'), ErrorCode.UnexpectedEndOfString);
1021
1017
  return true;
1022
- case 6 /* InvalidCharacter */:
1018
+ case 6 /* Json.ScanError.InvalidCharacter */:
1023
1019
  _error(localize('InvalidCharacter', 'Invalid characters in string. Control characters must be escaped.'), ErrorCode.InvalidCharacter);
1024
1020
  return true;
1025
1021
  }
@@ -1033,21 +1029,21 @@ export function parse(textDocument, config) {
1033
1029
  return node;
1034
1030
  }
1035
1031
  function _parseArray(parent) {
1036
- if (scanner.getToken() !== 3 /* OpenBracketToken */) {
1032
+ if (scanner.getToken() !== 3 /* Json.SyntaxKind.OpenBracketToken */) {
1037
1033
  return undefined;
1038
1034
  }
1039
- var node = new ArrayASTNodeImpl(parent, scanner.getTokenOffset());
1035
+ const node = new ArrayASTNodeImpl(parent, scanner.getTokenOffset());
1040
1036
  _scanNext(); // consume OpenBracketToken
1041
- var count = 0;
1042
- var needsComma = false;
1043
- while (scanner.getToken() !== 4 /* CloseBracketToken */ && scanner.getToken() !== 17 /* EOF */) {
1044
- if (scanner.getToken() === 5 /* CommaToken */) {
1037
+ const count = 0;
1038
+ let needsComma = false;
1039
+ while (scanner.getToken() !== 4 /* Json.SyntaxKind.CloseBracketToken */ && scanner.getToken() !== 17 /* Json.SyntaxKind.EOF */) {
1040
+ if (scanner.getToken() === 5 /* Json.SyntaxKind.CommaToken */) {
1045
1041
  if (!needsComma) {
1046
1042
  _error(localize('ValueExpected', 'Value expected'), ErrorCode.ValueExpected);
1047
1043
  }
1048
- var commaOffset = scanner.getTokenOffset();
1044
+ const commaOffset = scanner.getTokenOffset();
1049
1045
  _scanNext(); // consume comma
1050
- if (scanner.getToken() === 4 /* CloseBracketToken */) {
1046
+ if (scanner.getToken() === 4 /* Json.SyntaxKind.CloseBracketToken */) {
1051
1047
  if (needsComma) {
1052
1048
  _errorAtRange(localize('TrailingComma', 'Trailing comma'), ErrorCode.TrailingComma, commaOffset, commaOffset + 1);
1053
1049
  }
@@ -1057,29 +1053,29 @@ export function parse(textDocument, config) {
1057
1053
  else if (needsComma) {
1058
1054
  _error(localize('ExpectedComma', 'Expected comma'), ErrorCode.CommaExpected);
1059
1055
  }
1060
- var item = _parseValue(node);
1056
+ const item = _parseValue(node);
1061
1057
  if (!item) {
1062
- _error(localize('PropertyExpected', 'Value expected'), ErrorCode.ValueExpected, undefined, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]);
1058
+ _error(localize('PropertyExpected', 'Value expected'), ErrorCode.ValueExpected, undefined, [], [4 /* Json.SyntaxKind.CloseBracketToken */, 5 /* Json.SyntaxKind.CommaToken */]);
1063
1059
  }
1064
1060
  else {
1065
1061
  node.items.push(item);
1066
1062
  }
1067
1063
  needsComma = true;
1068
1064
  }
1069
- if (scanner.getToken() !== 4 /* CloseBracketToken */) {
1065
+ if (scanner.getToken() !== 4 /* Json.SyntaxKind.CloseBracketToken */) {
1070
1066
  return _error(localize('ExpectedCloseBracket', 'Expected comma or closing bracket'), ErrorCode.CommaOrCloseBacketExpected, node);
1071
1067
  }
1072
1068
  return _finalize(node, true);
1073
1069
  }
1074
- var keyPlaceholder = new StringASTNodeImpl(undefined, 0, 0);
1070
+ const keyPlaceholder = new StringASTNodeImpl(undefined, 0, 0);
1075
1071
  function _parseProperty(parent, keysSeen) {
1076
- var node = new PropertyASTNodeImpl(parent, scanner.getTokenOffset(), keyPlaceholder);
1077
- var key = _parseString(node);
1072
+ const node = new PropertyASTNodeImpl(parent, scanner.getTokenOffset(), keyPlaceholder);
1073
+ let key = _parseString(node);
1078
1074
  if (!key) {
1079
- if (scanner.getToken() === 16 /* Unknown */) {
1075
+ if (scanner.getToken() === 16 /* Json.SyntaxKind.Unknown */) {
1080
1076
  // give a more helpful error message
1081
1077
  _error(localize('DoubleQuotesExpected', 'Property keys must be doublequoted'), ErrorCode.Undefined);
1082
- var keyNode = new StringASTNodeImpl(node, scanner.getTokenOffset(), scanner.getTokenLength());
1078
+ const keyNode = new StringASTNodeImpl(node, scanner.getTokenOffset(), scanner.getTokenLength());
1083
1079
  keyNode.value = scanner.getTokenValue();
1084
1080
  key = keyNode;
1085
1081
  _scanNext(); // consume Unknown
@@ -1089,52 +1085,56 @@ export function parse(textDocument, config) {
1089
1085
  }
1090
1086
  }
1091
1087
  node.keyNode = key;
1092
- var seen = keysSeen[key.value];
1093
- if (seen) {
1094
- _errorAtRange(localize('DuplicateKeyWarning', "Duplicate object key"), ErrorCode.DuplicateKey, node.keyNode.offset, node.keyNode.offset + node.keyNode.length, DiagnosticSeverity.Warning);
1095
- if (typeof seen === 'object') {
1096
- _errorAtRange(localize('DuplicateKeyWarning', "Duplicate object key"), ErrorCode.DuplicateKey, seen.keyNode.offset, seen.keyNode.offset + seen.keyNode.length, DiagnosticSeverity.Warning);
1088
+ // For JSON files that forbid code comments, there is a convention to use the key name "//" to add comments.
1089
+ // Multiple instances of "//" are okay.
1090
+ if (key.value !== "//") {
1091
+ const seen = keysSeen[key.value];
1092
+ if (seen) {
1093
+ _errorAtRange(localize('DuplicateKeyWarning', "Duplicate object key"), ErrorCode.DuplicateKey, node.keyNode.offset, node.keyNode.offset + node.keyNode.length, DiagnosticSeverity.Warning);
1094
+ if (isObject(seen)) {
1095
+ _errorAtRange(localize('DuplicateKeyWarning', "Duplicate object key"), ErrorCode.DuplicateKey, seen.keyNode.offset, seen.keyNode.offset + seen.keyNode.length, DiagnosticSeverity.Warning);
1096
+ }
1097
+ keysSeen[key.value] = true; // if the same key is duplicate again, avoid duplicate error reporting
1098
+ }
1099
+ else {
1100
+ keysSeen[key.value] = node;
1097
1101
  }
1098
- keysSeen[key.value] = true; // if the same key is duplicate again, avoid duplicate error reporting
1099
- }
1100
- else {
1101
- keysSeen[key.value] = node;
1102
1102
  }
1103
- if (scanner.getToken() === 6 /* ColonToken */) {
1103
+ if (scanner.getToken() === 6 /* Json.SyntaxKind.ColonToken */) {
1104
1104
  node.colonOffset = scanner.getTokenOffset();
1105
1105
  _scanNext(); // consume ColonToken
1106
1106
  }
1107
1107
  else {
1108
1108
  _error(localize('ColonExpected', 'Colon expected'), ErrorCode.ColonExpected);
1109
- if (scanner.getToken() === 10 /* StringLiteral */ && textDocument.positionAt(key.offset + key.length).line < textDocument.positionAt(scanner.getTokenOffset()).line) {
1109
+ if (scanner.getToken() === 10 /* Json.SyntaxKind.StringLiteral */ && textDocument.positionAt(key.offset + key.length).line < textDocument.positionAt(scanner.getTokenOffset()).line) {
1110
1110
  node.length = key.length;
1111
1111
  return node;
1112
1112
  }
1113
1113
  }
1114
- var value = _parseValue(node);
1114
+ const value = _parseValue(node);
1115
1115
  if (!value) {
1116
- return _error(localize('ValueExpected', 'Value expected'), ErrorCode.ValueExpected, node, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
1116
+ return _error(localize('ValueExpected', 'Value expected'), ErrorCode.ValueExpected, node, [], [2 /* Json.SyntaxKind.CloseBraceToken */, 5 /* Json.SyntaxKind.CommaToken */]);
1117
1117
  }
1118
1118
  node.valueNode = value;
1119
1119
  node.length = value.offset + value.length - node.offset;
1120
1120
  return node;
1121
1121
  }
1122
1122
  function _parseObject(parent) {
1123
- if (scanner.getToken() !== 1 /* OpenBraceToken */) {
1123
+ if (scanner.getToken() !== 1 /* Json.SyntaxKind.OpenBraceToken */) {
1124
1124
  return undefined;
1125
1125
  }
1126
- var node = new ObjectASTNodeImpl(parent, scanner.getTokenOffset());
1127
- var keysSeen = Object.create(null);
1126
+ const node = new ObjectASTNodeImpl(parent, scanner.getTokenOffset());
1127
+ const keysSeen = Object.create(null);
1128
1128
  _scanNext(); // consume OpenBraceToken
1129
- var needsComma = false;
1130
- while (scanner.getToken() !== 2 /* CloseBraceToken */ && scanner.getToken() !== 17 /* EOF */) {
1131
- if (scanner.getToken() === 5 /* CommaToken */) {
1129
+ let needsComma = false;
1130
+ while (scanner.getToken() !== 2 /* Json.SyntaxKind.CloseBraceToken */ && scanner.getToken() !== 17 /* Json.SyntaxKind.EOF */) {
1131
+ if (scanner.getToken() === 5 /* Json.SyntaxKind.CommaToken */) {
1132
1132
  if (!needsComma) {
1133
1133
  _error(localize('PropertyExpected', 'Property expected'), ErrorCode.PropertyExpected);
1134
1134
  }
1135
- var commaOffset = scanner.getTokenOffset();
1135
+ const commaOffset = scanner.getTokenOffset();
1136
1136
  _scanNext(); // consume comma
1137
- if (scanner.getToken() === 2 /* CloseBraceToken */) {
1137
+ if (scanner.getToken() === 2 /* Json.SyntaxKind.CloseBraceToken */) {
1138
1138
  if (needsComma) {
1139
1139
  _errorAtRange(localize('TrailingComma', 'Trailing comma'), ErrorCode.TrailingComma, commaOffset, commaOffset + 1);
1140
1140
  }
@@ -1144,37 +1144,37 @@ export function parse(textDocument, config) {
1144
1144
  else if (needsComma) {
1145
1145
  _error(localize('ExpectedComma', 'Expected comma'), ErrorCode.CommaExpected);
1146
1146
  }
1147
- var property = _parseProperty(node, keysSeen);
1147
+ const property = _parseProperty(node, keysSeen);
1148
1148
  if (!property) {
1149
- _error(localize('PropertyExpected', 'Property expected'), ErrorCode.PropertyExpected, undefined, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
1149
+ _error(localize('PropertyExpected', 'Property expected'), ErrorCode.PropertyExpected, undefined, [], [2 /* Json.SyntaxKind.CloseBraceToken */, 5 /* Json.SyntaxKind.CommaToken */]);
1150
1150
  }
1151
1151
  else {
1152
1152
  node.properties.push(property);
1153
1153
  }
1154
1154
  needsComma = true;
1155
1155
  }
1156
- if (scanner.getToken() !== 2 /* CloseBraceToken */) {
1156
+ if (scanner.getToken() !== 2 /* Json.SyntaxKind.CloseBraceToken */) {
1157
1157
  return _error(localize('ExpectedCloseBrace', 'Expected comma or closing brace'), ErrorCode.CommaOrCloseBraceExpected, node);
1158
1158
  }
1159
1159
  return _finalize(node, true);
1160
1160
  }
1161
1161
  function _parseString(parent) {
1162
- if (scanner.getToken() !== 10 /* StringLiteral */) {
1162
+ if (scanner.getToken() !== 10 /* Json.SyntaxKind.StringLiteral */) {
1163
1163
  return undefined;
1164
1164
  }
1165
- var node = new StringASTNodeImpl(parent, scanner.getTokenOffset());
1165
+ const node = new StringASTNodeImpl(parent, scanner.getTokenOffset());
1166
1166
  node.value = scanner.getTokenValue();
1167
1167
  return _finalize(node, true);
1168
1168
  }
1169
1169
  function _parseNumber(parent) {
1170
- if (scanner.getToken() !== 11 /* NumericLiteral */) {
1170
+ if (scanner.getToken() !== 11 /* Json.SyntaxKind.NumericLiteral */) {
1171
1171
  return undefined;
1172
1172
  }
1173
- var node = new NumberASTNodeImpl(parent, scanner.getTokenOffset());
1174
- if (scanner.getTokenError() === 0 /* None */) {
1175
- var tokenValue = scanner.getTokenValue();
1173
+ const node = new NumberASTNodeImpl(parent, scanner.getTokenOffset());
1174
+ if (scanner.getTokenError() === 0 /* Json.ScanError.None */) {
1175
+ const tokenValue = scanner.getTokenValue();
1176
1176
  try {
1177
- var numberValue = JSON.parse(tokenValue);
1177
+ const numberValue = JSON.parse(tokenValue);
1178
1178
  if (!isNumber(numberValue)) {
1179
1179
  return _error(localize('InvalidNumberFormat', 'Invalid number format.'), ErrorCode.Undefined, node);
1180
1180
  }
@@ -1188,13 +1188,13 @@ export function parse(textDocument, config) {
1188
1188
  return _finalize(node, true);
1189
1189
  }
1190
1190
  function _parseLiteral(parent) {
1191
- var node;
1191
+ let node;
1192
1192
  switch (scanner.getToken()) {
1193
- case 7 /* NullKeyword */:
1193
+ case 7 /* Json.SyntaxKind.NullKeyword */:
1194
1194
  return _finalize(new NullASTNodeImpl(parent, scanner.getTokenOffset()), true);
1195
- case 8 /* TrueKeyword */:
1195
+ case 8 /* Json.SyntaxKind.TrueKeyword */:
1196
1196
  return _finalize(new BooleanASTNodeImpl(parent, true, scanner.getTokenOffset()), true);
1197
- case 9 /* FalseKeyword */:
1197
+ case 9 /* Json.SyntaxKind.FalseKeyword */:
1198
1198
  return _finalize(new BooleanASTNodeImpl(parent, false, scanner.getTokenOffset()), true);
1199
1199
  default:
1200
1200
  return undefined;
@@ -1203,14 +1203,14 @@ export function parse(textDocument, config) {
1203
1203
  function _parseValue(parent) {
1204
1204
  return _parseArray(parent) || _parseObject(parent) || _parseString(parent) || _parseNumber(parent) || _parseLiteral(parent);
1205
1205
  }
1206
- var _root = undefined;
1207
- var token = _scanNext();
1208
- if (token !== 17 /* EOF */) {
1206
+ let _root = undefined;
1207
+ const token = _scanNext();
1208
+ if (token !== 17 /* Json.SyntaxKind.EOF */) {
1209
1209
  _root = _parseValue(_root);
1210
1210
  if (!_root) {
1211
1211
  _error(localize('Invalid symbol', 'Expected a JSON object, array or literal.'), ErrorCode.Undefined);
1212
1212
  }
1213
- else if (scanner.getToken() !== 17 /* EOF */) {
1213
+ else if (scanner.getToken() !== 17 /* Json.SyntaxKind.EOF */) {
1214
1214
  _error(localize('End of file expected', 'End of file expected.'), ErrorCode.Undefined);
1215
1215
  }
1216
1216
  }