vscode-json-languageservice 4.1.8
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 +133 -0
- package/LICENSE.md +47 -0
- package/README.md +65 -0
- package/lib/esm/jsonContributions.d.ts +17 -0
- package/lib/esm/jsonContributions.js +1 -0
- package/lib/esm/jsonLanguageService.d.ts +28 -0
- package/lib/esm/jsonLanguageService.js +65 -0
- package/lib/esm/jsonLanguageTypes.d.ts +275 -0
- package/lib/esm/jsonLanguageTypes.js +45 -0
- package/lib/esm/jsonSchema.d.ts +70 -0
- package/lib/esm/jsonSchema.js +1 -0
- package/lib/esm/parser/jsonParser.js +1212 -0
- package/lib/esm/services/configuration.js +528 -0
- package/lib/esm/services/jsonCompletion.js +934 -0
- package/lib/esm/services/jsonDocumentSymbols.js +278 -0
- package/lib/esm/services/jsonFolding.js +121 -0
- package/lib/esm/services/jsonHover.js +112 -0
- package/lib/esm/services/jsonLinks.js +73 -0
- package/lib/esm/services/jsonSchemaService.js +535 -0
- package/lib/esm/services/jsonSelectionRanges.js +61 -0
- package/lib/esm/services/jsonValidation.js +146 -0
- package/lib/esm/utils/colors.js +69 -0
- package/lib/esm/utils/glob.js +124 -0
- package/lib/esm/utils/json.js +42 -0
- package/lib/esm/utils/objects.js +65 -0
- package/lib/esm/utils/strings.js +52 -0
- package/lib/umd/jsonContributions.d.ts +17 -0
- package/lib/umd/jsonContributions.js +12 -0
- package/lib/umd/jsonLanguageService.d.ts +28 -0
- package/lib/umd/jsonLanguageService.js +89 -0
- package/lib/umd/jsonLanguageTypes.d.ts +275 -0
- package/lib/umd/jsonLanguageTypes.js +92 -0
- package/lib/umd/jsonSchema.d.ts +70 -0
- package/lib/umd/jsonSchema.js +12 -0
- package/lib/umd/parser/jsonParser.js +1231 -0
- package/lib/umd/services/configuration.js +541 -0
- package/lib/umd/services/jsonCompletion.js +947 -0
- package/lib/umd/services/jsonDocumentSymbols.js +291 -0
- package/lib/umd/services/jsonFolding.js +135 -0
- package/lib/umd/services/jsonHover.js +125 -0
- package/lib/umd/services/jsonLinks.js +87 -0
- package/lib/umd/services/jsonSchemaService.js +548 -0
- package/lib/umd/services/jsonSelectionRanges.js +75 -0
- package/lib/umd/services/jsonValidation.js +159 -0
- package/lib/umd/utils/colors.js +85 -0
- package/lib/umd/utils/glob.js +138 -0
- package/lib/umd/utils/json.js +56 -0
- package/lib/umd/utils/objects.js +83 -0
- package/lib/umd/utils/strings.js +70 -0
- package/package.json +55 -0
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
(function (factory) {
|
|
6
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
7
|
+
var v = factory(require, exports);
|
|
8
|
+
if (v !== undefined) module.exports = v;
|
|
9
|
+
}
|
|
10
|
+
else if (typeof define === "function" && define.amd) {
|
|
11
|
+
define(["require", "exports", "jsonc-parser", "vscode-uri", "../utils/strings", "../parser/jsonParser", "vscode-nls", "../utils/glob"], factory);
|
|
12
|
+
}
|
|
13
|
+
})(function (require, exports) {
|
|
14
|
+
"use strict";
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.JSONSchemaService = exports.ResolvedSchema = exports.UnresolvedSchema = void 0;
|
|
17
|
+
var Json = require("jsonc-parser");
|
|
18
|
+
var vscode_uri_1 = require("vscode-uri");
|
|
19
|
+
var Strings = require("../utils/strings");
|
|
20
|
+
var Parser = require("../parser/jsonParser");
|
|
21
|
+
var nls = require("vscode-nls");
|
|
22
|
+
var glob_1 = require("../utils/glob");
|
|
23
|
+
var localize = nls.loadMessageBundle();
|
|
24
|
+
var BANG = '!';
|
|
25
|
+
var PATH_SEP = '/';
|
|
26
|
+
var FilePatternAssociation = /** @class */ (function () {
|
|
27
|
+
function FilePatternAssociation(pattern, uris) {
|
|
28
|
+
this.globWrappers = [];
|
|
29
|
+
try {
|
|
30
|
+
for (var _i = 0, pattern_1 = pattern; _i < pattern_1.length; _i++) {
|
|
31
|
+
var patternString = pattern_1[_i];
|
|
32
|
+
var include = patternString[0] !== BANG;
|
|
33
|
+
if (!include) {
|
|
34
|
+
patternString = patternString.substring(1);
|
|
35
|
+
}
|
|
36
|
+
if (patternString.length > 0) {
|
|
37
|
+
if (patternString[0] === PATH_SEP) {
|
|
38
|
+
patternString = patternString.substring(1);
|
|
39
|
+
}
|
|
40
|
+
this.globWrappers.push({
|
|
41
|
+
regexp: glob_1.createRegex('**/' + patternString, { extended: true, globstar: true }),
|
|
42
|
+
include: include,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
;
|
|
47
|
+
this.uris = uris;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
this.globWrappers.length = 0;
|
|
51
|
+
this.uris = [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
FilePatternAssociation.prototype.matchesPattern = function (fileName) {
|
|
55
|
+
var match = false;
|
|
56
|
+
for (var _i = 0, _a = this.globWrappers; _i < _a.length; _i++) {
|
|
57
|
+
var _b = _a[_i], regexp = _b.regexp, include = _b.include;
|
|
58
|
+
if (regexp.test(fileName)) {
|
|
59
|
+
match = include;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return match;
|
|
63
|
+
};
|
|
64
|
+
FilePatternAssociation.prototype.getURIs = function () {
|
|
65
|
+
return this.uris;
|
|
66
|
+
};
|
|
67
|
+
return FilePatternAssociation;
|
|
68
|
+
}());
|
|
69
|
+
var SchemaHandle = /** @class */ (function () {
|
|
70
|
+
function SchemaHandle(service, url, unresolvedSchemaContent) {
|
|
71
|
+
this.service = service;
|
|
72
|
+
this.url = url;
|
|
73
|
+
this.dependencies = {};
|
|
74
|
+
if (unresolvedSchemaContent) {
|
|
75
|
+
this.unresolvedSchema = this.service.promise.resolve(new UnresolvedSchema(unresolvedSchemaContent));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
SchemaHandle.prototype.getUnresolvedSchema = function () {
|
|
79
|
+
if (!this.unresolvedSchema) {
|
|
80
|
+
this.unresolvedSchema = this.service.loadSchema(this.url);
|
|
81
|
+
}
|
|
82
|
+
return this.unresolvedSchema;
|
|
83
|
+
};
|
|
84
|
+
SchemaHandle.prototype.getResolvedSchema = function () {
|
|
85
|
+
var _this = this;
|
|
86
|
+
if (!this.resolvedSchema) {
|
|
87
|
+
this.resolvedSchema = this.getUnresolvedSchema().then(function (unresolved) {
|
|
88
|
+
return _this.service.resolveSchemaContent(unresolved, _this.url, _this.dependencies);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return this.resolvedSchema;
|
|
92
|
+
};
|
|
93
|
+
SchemaHandle.prototype.clearSchema = function () {
|
|
94
|
+
this.resolvedSchema = undefined;
|
|
95
|
+
this.unresolvedSchema = undefined;
|
|
96
|
+
this.dependencies = {};
|
|
97
|
+
};
|
|
98
|
+
return SchemaHandle;
|
|
99
|
+
}());
|
|
100
|
+
var UnresolvedSchema = /** @class */ (function () {
|
|
101
|
+
function UnresolvedSchema(schema, errors) {
|
|
102
|
+
if (errors === void 0) { errors = []; }
|
|
103
|
+
this.schema = schema;
|
|
104
|
+
this.errors = errors;
|
|
105
|
+
}
|
|
106
|
+
return UnresolvedSchema;
|
|
107
|
+
}());
|
|
108
|
+
exports.UnresolvedSchema = UnresolvedSchema;
|
|
109
|
+
var ResolvedSchema = /** @class */ (function () {
|
|
110
|
+
function ResolvedSchema(schema, errors) {
|
|
111
|
+
if (errors === void 0) { errors = []; }
|
|
112
|
+
this.schema = schema;
|
|
113
|
+
this.errors = errors;
|
|
114
|
+
}
|
|
115
|
+
ResolvedSchema.prototype.getSection = function (path) {
|
|
116
|
+
var schemaRef = this.getSectionRecursive(path, this.schema);
|
|
117
|
+
if (schemaRef) {
|
|
118
|
+
return Parser.asSchema(schemaRef);
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
};
|
|
122
|
+
ResolvedSchema.prototype.getSectionRecursive = function (path, schema) {
|
|
123
|
+
if (!schema || typeof schema === 'boolean' || path.length === 0) {
|
|
124
|
+
return schema;
|
|
125
|
+
}
|
|
126
|
+
var next = path.shift();
|
|
127
|
+
if (schema.properties && typeof schema.properties[next]) {
|
|
128
|
+
return this.getSectionRecursive(path, schema.properties[next]);
|
|
129
|
+
}
|
|
130
|
+
else if (schema.patternProperties) {
|
|
131
|
+
for (var _i = 0, _a = Object.keys(schema.patternProperties); _i < _a.length; _i++) {
|
|
132
|
+
var pattern = _a[_i];
|
|
133
|
+
var regex = Strings.extendedRegExp(pattern);
|
|
134
|
+
if (regex.test(next)) {
|
|
135
|
+
return this.getSectionRecursive(path, schema.patternProperties[pattern]);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (typeof schema.additionalProperties === 'object') {
|
|
140
|
+
return this.getSectionRecursive(path, schema.additionalProperties);
|
|
141
|
+
}
|
|
142
|
+
else if (next.match('[0-9]+')) {
|
|
143
|
+
if (Array.isArray(schema.items)) {
|
|
144
|
+
var index = parseInt(next, 10);
|
|
145
|
+
if (!isNaN(index) && schema.items[index]) {
|
|
146
|
+
return this.getSectionRecursive(path, schema.items[index]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (schema.items) {
|
|
150
|
+
return this.getSectionRecursive(path, schema.items);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return undefined;
|
|
154
|
+
};
|
|
155
|
+
return ResolvedSchema;
|
|
156
|
+
}());
|
|
157
|
+
exports.ResolvedSchema = ResolvedSchema;
|
|
158
|
+
var JSONSchemaService = /** @class */ (function () {
|
|
159
|
+
function JSONSchemaService(requestService, contextService, promiseConstructor) {
|
|
160
|
+
this.contextService = contextService;
|
|
161
|
+
this.requestService = requestService;
|
|
162
|
+
this.promiseConstructor = promiseConstructor || Promise;
|
|
163
|
+
this.callOnDispose = [];
|
|
164
|
+
this.contributionSchemas = {};
|
|
165
|
+
this.contributionAssociations = [];
|
|
166
|
+
this.schemasById = {};
|
|
167
|
+
this.filePatternAssociations = [];
|
|
168
|
+
this.registeredSchemasIds = {};
|
|
169
|
+
}
|
|
170
|
+
JSONSchemaService.prototype.getRegisteredSchemaIds = function (filter) {
|
|
171
|
+
return Object.keys(this.registeredSchemasIds).filter(function (id) {
|
|
172
|
+
var scheme = vscode_uri_1.URI.parse(id).scheme;
|
|
173
|
+
return scheme !== 'schemaservice' && (!filter || filter(scheme));
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
Object.defineProperty(JSONSchemaService.prototype, "promise", {
|
|
177
|
+
get: function () {
|
|
178
|
+
return this.promiseConstructor;
|
|
179
|
+
},
|
|
180
|
+
enumerable: false,
|
|
181
|
+
configurable: true
|
|
182
|
+
});
|
|
183
|
+
JSONSchemaService.prototype.dispose = function () {
|
|
184
|
+
while (this.callOnDispose.length > 0) {
|
|
185
|
+
this.callOnDispose.pop()();
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
JSONSchemaService.prototype.onResourceChange = function (uri) {
|
|
189
|
+
var _this = this;
|
|
190
|
+
// always clear this local cache when a resource changes
|
|
191
|
+
this.cachedSchemaForResource = undefined;
|
|
192
|
+
var hasChanges = false;
|
|
193
|
+
uri = normalizeId(uri);
|
|
194
|
+
var toWalk = [uri];
|
|
195
|
+
var all = Object.keys(this.schemasById).map(function (key) { return _this.schemasById[key]; });
|
|
196
|
+
while (toWalk.length) {
|
|
197
|
+
var curr = toWalk.pop();
|
|
198
|
+
for (var i = 0; i < all.length; i++) {
|
|
199
|
+
var handle = all[i];
|
|
200
|
+
if (handle && (handle.url === curr || handle.dependencies[curr])) {
|
|
201
|
+
if (handle.url !== curr) {
|
|
202
|
+
toWalk.push(handle.url);
|
|
203
|
+
}
|
|
204
|
+
handle.clearSchema();
|
|
205
|
+
all[i] = undefined;
|
|
206
|
+
hasChanges = true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return hasChanges;
|
|
211
|
+
};
|
|
212
|
+
JSONSchemaService.prototype.setSchemaContributions = function (schemaContributions) {
|
|
213
|
+
if (schemaContributions.schemas) {
|
|
214
|
+
var schemas = schemaContributions.schemas;
|
|
215
|
+
for (var id in schemas) {
|
|
216
|
+
var normalizedId = normalizeId(id);
|
|
217
|
+
this.contributionSchemas[normalizedId] = this.addSchemaHandle(normalizedId, schemas[id]);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (Array.isArray(schemaContributions.schemaAssociations)) {
|
|
221
|
+
var schemaAssociations = schemaContributions.schemaAssociations;
|
|
222
|
+
for (var _i = 0, schemaAssociations_1 = schemaAssociations; _i < schemaAssociations_1.length; _i++) {
|
|
223
|
+
var schemaAssociation = schemaAssociations_1[_i];
|
|
224
|
+
var uris = schemaAssociation.uris.map(normalizeId);
|
|
225
|
+
var association = this.addFilePatternAssociation(schemaAssociation.pattern, uris);
|
|
226
|
+
this.contributionAssociations.push(association);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
JSONSchemaService.prototype.addSchemaHandle = function (id, unresolvedSchemaContent) {
|
|
231
|
+
var schemaHandle = new SchemaHandle(this, id, unresolvedSchemaContent);
|
|
232
|
+
this.schemasById[id] = schemaHandle;
|
|
233
|
+
return schemaHandle;
|
|
234
|
+
};
|
|
235
|
+
JSONSchemaService.prototype.getOrAddSchemaHandle = function (id, unresolvedSchemaContent) {
|
|
236
|
+
return this.schemasById[id] || this.addSchemaHandle(id, unresolvedSchemaContent);
|
|
237
|
+
};
|
|
238
|
+
JSONSchemaService.prototype.addFilePatternAssociation = function (pattern, uris) {
|
|
239
|
+
var fpa = new FilePatternAssociation(pattern, uris);
|
|
240
|
+
this.filePatternAssociations.push(fpa);
|
|
241
|
+
return fpa;
|
|
242
|
+
};
|
|
243
|
+
JSONSchemaService.prototype.registerExternalSchema = function (uri, filePatterns, unresolvedSchemaContent) {
|
|
244
|
+
var id = normalizeId(uri);
|
|
245
|
+
this.registeredSchemasIds[id] = true;
|
|
246
|
+
this.cachedSchemaForResource = undefined;
|
|
247
|
+
if (filePatterns) {
|
|
248
|
+
this.addFilePatternAssociation(filePatterns, [uri]);
|
|
249
|
+
}
|
|
250
|
+
return unresolvedSchemaContent ? this.addSchemaHandle(id, unresolvedSchemaContent) : this.getOrAddSchemaHandle(id);
|
|
251
|
+
};
|
|
252
|
+
JSONSchemaService.prototype.clearExternalSchemas = function () {
|
|
253
|
+
this.schemasById = {};
|
|
254
|
+
this.filePatternAssociations = [];
|
|
255
|
+
this.registeredSchemasIds = {};
|
|
256
|
+
this.cachedSchemaForResource = undefined;
|
|
257
|
+
for (var id in this.contributionSchemas) {
|
|
258
|
+
this.schemasById[id] = this.contributionSchemas[id];
|
|
259
|
+
this.registeredSchemasIds[id] = true;
|
|
260
|
+
}
|
|
261
|
+
for (var _i = 0, _a = this.contributionAssociations; _i < _a.length; _i++) {
|
|
262
|
+
var contributionAssociation = _a[_i];
|
|
263
|
+
this.filePatternAssociations.push(contributionAssociation);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
JSONSchemaService.prototype.getResolvedSchema = function (schemaId) {
|
|
267
|
+
var id = normalizeId(schemaId);
|
|
268
|
+
var schemaHandle = this.schemasById[id];
|
|
269
|
+
if (schemaHandle) {
|
|
270
|
+
return schemaHandle.getResolvedSchema();
|
|
271
|
+
}
|
|
272
|
+
return this.promise.resolve(undefined);
|
|
273
|
+
};
|
|
274
|
+
JSONSchemaService.prototype.loadSchema = function (url) {
|
|
275
|
+
if (!this.requestService) {
|
|
276
|
+
var errorMessage = localize('json.schema.norequestservice', 'Unable to load schema from \'{0}\'. No schema request service available', toDisplayString(url));
|
|
277
|
+
return this.promise.resolve(new UnresolvedSchema({}, [errorMessage]));
|
|
278
|
+
}
|
|
279
|
+
return this.requestService(url).then(function (content) {
|
|
280
|
+
if (!content) {
|
|
281
|
+
var errorMessage = localize('json.schema.nocontent', 'Unable to load schema from \'{0}\': No content.', toDisplayString(url));
|
|
282
|
+
return new UnresolvedSchema({}, [errorMessage]);
|
|
283
|
+
}
|
|
284
|
+
var schemaContent = {};
|
|
285
|
+
var jsonErrors = [];
|
|
286
|
+
schemaContent = Json.parse(content, jsonErrors);
|
|
287
|
+
var errors = jsonErrors.length ? [localize('json.schema.invalidFormat', 'Unable to parse content from \'{0}\': Parse error at offset {1}.', toDisplayString(url), jsonErrors[0].offset)] : [];
|
|
288
|
+
return new UnresolvedSchema(schemaContent, errors);
|
|
289
|
+
}, function (error) {
|
|
290
|
+
var errorMessage = error.toString();
|
|
291
|
+
var errorSplit = error.toString().split('Error: ');
|
|
292
|
+
if (errorSplit.length > 1) {
|
|
293
|
+
// more concise error message, URL and context are attached by caller anyways
|
|
294
|
+
errorMessage = errorSplit[1];
|
|
295
|
+
}
|
|
296
|
+
if (Strings.endsWith(errorMessage, '.')) {
|
|
297
|
+
errorMessage = errorMessage.substr(0, errorMessage.length - 1);
|
|
298
|
+
}
|
|
299
|
+
return new UnresolvedSchema({}, [localize('json.schema.nocontent', 'Unable to load schema from \'{0}\': {1}.', toDisplayString(url), errorMessage)]);
|
|
300
|
+
});
|
|
301
|
+
};
|
|
302
|
+
JSONSchemaService.prototype.resolveSchemaContent = function (schemaToResolve, schemaURL, dependencies) {
|
|
303
|
+
var _this = this;
|
|
304
|
+
var resolveErrors = schemaToResolve.errors.slice(0);
|
|
305
|
+
var schema = schemaToResolve.schema;
|
|
306
|
+
if (schema.$schema) {
|
|
307
|
+
var id = normalizeId(schema.$schema);
|
|
308
|
+
if (id === 'http://json-schema.org/draft-03/schema') {
|
|
309
|
+
return this.promise.resolve(new ResolvedSchema({}, [localize('json.schema.draft03.notsupported', "Draft-03 schemas are not supported.")]));
|
|
310
|
+
}
|
|
311
|
+
else if (id === 'https://json-schema.org/draft/2019-09/schema') {
|
|
312
|
+
resolveErrors.push(localize('json.schema.draft201909.notsupported', "Draft 2019-09 schemas are not yet fully supported."));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
var contextService = this.contextService;
|
|
316
|
+
var findSection = function (schema, path) {
|
|
317
|
+
if (!path) {
|
|
318
|
+
return schema;
|
|
319
|
+
}
|
|
320
|
+
var current = schema;
|
|
321
|
+
if (path[0] === '/') {
|
|
322
|
+
path = path.substr(1);
|
|
323
|
+
}
|
|
324
|
+
path.split('/').some(function (part) {
|
|
325
|
+
part = part.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
326
|
+
current = current[part];
|
|
327
|
+
return !current;
|
|
328
|
+
});
|
|
329
|
+
return current;
|
|
330
|
+
};
|
|
331
|
+
var merge = function (target, sourceRoot, sourceURI, refSegment) {
|
|
332
|
+
var path = refSegment ? decodeURIComponent(refSegment) : undefined;
|
|
333
|
+
var section = findSection(sourceRoot, path);
|
|
334
|
+
if (section) {
|
|
335
|
+
for (var key in section) {
|
|
336
|
+
if (section.hasOwnProperty(key) && !target.hasOwnProperty(key)) {
|
|
337
|
+
target[key] = section[key];
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
resolveErrors.push(localize('json.schema.invalidref', '$ref \'{0}\' in \'{1}\' can not be resolved.', path, sourceURI));
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
var resolveExternalLink = function (node, uri, refSegment, parentSchemaURL, parentSchemaDependencies) {
|
|
346
|
+
if (contextService && !/^[A-Za-z][A-Za-z0-9+\-.+]*:\/\/.*/.test(uri)) {
|
|
347
|
+
uri = contextService.resolveRelativePath(uri, parentSchemaURL);
|
|
348
|
+
}
|
|
349
|
+
uri = normalizeId(uri);
|
|
350
|
+
var referencedHandle = _this.getOrAddSchemaHandle(uri);
|
|
351
|
+
return referencedHandle.getUnresolvedSchema().then(function (unresolvedSchema) {
|
|
352
|
+
parentSchemaDependencies[uri] = true;
|
|
353
|
+
if (unresolvedSchema.errors.length) {
|
|
354
|
+
var loc = refSegment ? uri + '#' + refSegment : uri;
|
|
355
|
+
resolveErrors.push(localize('json.schema.problemloadingref', 'Problems loading reference \'{0}\': {1}', loc, unresolvedSchema.errors[0]));
|
|
356
|
+
}
|
|
357
|
+
merge(node, unresolvedSchema.schema, uri, refSegment);
|
|
358
|
+
return resolveRefs(node, unresolvedSchema.schema, uri, referencedHandle.dependencies);
|
|
359
|
+
});
|
|
360
|
+
};
|
|
361
|
+
var resolveRefs = function (node, parentSchema, parentSchemaURL, parentSchemaDependencies) {
|
|
362
|
+
if (!node || typeof node !== 'object') {
|
|
363
|
+
return Promise.resolve(null);
|
|
364
|
+
}
|
|
365
|
+
var toWalk = [node];
|
|
366
|
+
var seen = [];
|
|
367
|
+
var openPromises = [];
|
|
368
|
+
var collectEntries = function () {
|
|
369
|
+
var entries = [];
|
|
370
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
371
|
+
entries[_i] = arguments[_i];
|
|
372
|
+
}
|
|
373
|
+
for (var _a = 0, entries_1 = entries; _a < entries_1.length; _a++) {
|
|
374
|
+
var entry = entries_1[_a];
|
|
375
|
+
if (typeof entry === 'object') {
|
|
376
|
+
toWalk.push(entry);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
var collectMapEntries = function () {
|
|
381
|
+
var maps = [];
|
|
382
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
383
|
+
maps[_i] = arguments[_i];
|
|
384
|
+
}
|
|
385
|
+
for (var _a = 0, maps_1 = maps; _a < maps_1.length; _a++) {
|
|
386
|
+
var map = maps_1[_a];
|
|
387
|
+
if (typeof map === 'object') {
|
|
388
|
+
for (var k in map) {
|
|
389
|
+
var key = k;
|
|
390
|
+
var entry = map[key];
|
|
391
|
+
if (typeof entry === 'object') {
|
|
392
|
+
toWalk.push(entry);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
var collectArrayEntries = function () {
|
|
399
|
+
var arrays = [];
|
|
400
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
401
|
+
arrays[_i] = arguments[_i];
|
|
402
|
+
}
|
|
403
|
+
for (var _a = 0, arrays_1 = arrays; _a < arrays_1.length; _a++) {
|
|
404
|
+
var array = arrays_1[_a];
|
|
405
|
+
if (Array.isArray(array)) {
|
|
406
|
+
for (var _b = 0, array_1 = array; _b < array_1.length; _b++) {
|
|
407
|
+
var entry = array_1[_b];
|
|
408
|
+
if (typeof entry === 'object') {
|
|
409
|
+
toWalk.push(entry);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
var handleRef = function (next) {
|
|
416
|
+
var seenRefs = [];
|
|
417
|
+
while (next.$ref) {
|
|
418
|
+
var ref = next.$ref;
|
|
419
|
+
var segments = ref.split('#', 2);
|
|
420
|
+
delete next.$ref;
|
|
421
|
+
if (segments[0].length > 0) {
|
|
422
|
+
openPromises.push(resolveExternalLink(next, segments[0], segments[1], parentSchemaURL, parentSchemaDependencies));
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
if (seenRefs.indexOf(ref) === -1) {
|
|
427
|
+
merge(next, parentSchema, parentSchemaURL, segments[1]); // can set next.$ref again, use seenRefs to avoid circle
|
|
428
|
+
seenRefs.push(ref);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
collectEntries(next.items, next.additionalItems, next.additionalProperties, next.not, next.contains, next.propertyNames, next.if, next.then, next.else);
|
|
433
|
+
collectMapEntries(next.definitions, next.properties, next.patternProperties, next.dependencies);
|
|
434
|
+
collectArrayEntries(next.anyOf, next.allOf, next.oneOf, next.items);
|
|
435
|
+
};
|
|
436
|
+
while (toWalk.length) {
|
|
437
|
+
var next = toWalk.pop();
|
|
438
|
+
if (seen.indexOf(next) >= 0) {
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
seen.push(next);
|
|
442
|
+
handleRef(next);
|
|
443
|
+
}
|
|
444
|
+
return _this.promise.all(openPromises);
|
|
445
|
+
};
|
|
446
|
+
return resolveRefs(schema, schema, schemaURL, dependencies).then(function (_) { return new ResolvedSchema(schema, resolveErrors); });
|
|
447
|
+
};
|
|
448
|
+
JSONSchemaService.prototype.getSchemaForResource = function (resource, document) {
|
|
449
|
+
// first use $schema if present
|
|
450
|
+
if (document && document.root && document.root.type === 'object') {
|
|
451
|
+
var schemaProperties = document.root.properties.filter(function (p) { return (p.keyNode.value === '$schema') && p.valueNode && p.valueNode.type === 'string'; });
|
|
452
|
+
if (schemaProperties.length > 0) {
|
|
453
|
+
var valueNode = schemaProperties[0].valueNode;
|
|
454
|
+
if (valueNode && valueNode.type === 'string') {
|
|
455
|
+
var schemeId = Parser.getNodeValue(valueNode);
|
|
456
|
+
if (schemeId && Strings.startsWith(schemeId, '.') && this.contextService) {
|
|
457
|
+
schemeId = this.contextService.resolveRelativePath(schemeId, resource);
|
|
458
|
+
}
|
|
459
|
+
if (schemeId) {
|
|
460
|
+
var id = normalizeId(schemeId);
|
|
461
|
+
return this.getOrAddSchemaHandle(id).getResolvedSchema();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (this.cachedSchemaForResource && this.cachedSchemaForResource.resource === resource) {
|
|
467
|
+
return this.cachedSchemaForResource.resolvedSchema;
|
|
468
|
+
}
|
|
469
|
+
var seen = Object.create(null);
|
|
470
|
+
var schemas = [];
|
|
471
|
+
var normalizedResource = normalizeResourceForMatching(resource);
|
|
472
|
+
for (var _i = 0, _a = this.filePatternAssociations; _i < _a.length; _i++) {
|
|
473
|
+
var entry = _a[_i];
|
|
474
|
+
if (entry.matchesPattern(normalizedResource)) {
|
|
475
|
+
for (var _b = 0, _c = entry.getURIs(); _b < _c.length; _b++) {
|
|
476
|
+
var schemaId = _c[_b];
|
|
477
|
+
if (!seen[schemaId]) {
|
|
478
|
+
schemas.push(schemaId);
|
|
479
|
+
seen[schemaId] = true;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
var resolvedSchema = schemas.length > 0 ? this.createCombinedSchema(resource, schemas).getResolvedSchema() : this.promise.resolve(undefined);
|
|
485
|
+
this.cachedSchemaForResource = { resource: resource, resolvedSchema: resolvedSchema };
|
|
486
|
+
return resolvedSchema;
|
|
487
|
+
};
|
|
488
|
+
JSONSchemaService.prototype.createCombinedSchema = function (resource, schemaIds) {
|
|
489
|
+
if (schemaIds.length === 1) {
|
|
490
|
+
return this.getOrAddSchemaHandle(schemaIds[0]);
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
var combinedSchemaId = 'schemaservice://combinedSchema/' + encodeURIComponent(resource);
|
|
494
|
+
var combinedSchema = {
|
|
495
|
+
allOf: schemaIds.map(function (schemaId) { return ({ $ref: schemaId }); })
|
|
496
|
+
};
|
|
497
|
+
return this.addSchemaHandle(combinedSchemaId, combinedSchema);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
JSONSchemaService.prototype.getMatchingSchemas = function (document, jsonDocument, schema) {
|
|
501
|
+
if (schema) {
|
|
502
|
+
var id = schema.id || ('schemaservice://untitled/matchingSchemas/' + idCounter++);
|
|
503
|
+
return this.resolveSchemaContent(new UnresolvedSchema(schema), id, {}).then(function (resolvedSchema) {
|
|
504
|
+
return jsonDocument.getMatchingSchemas(resolvedSchema.schema).filter(function (s) { return !s.inverted; });
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
return this.getSchemaForResource(document.uri, jsonDocument).then(function (schema) {
|
|
508
|
+
if (schema) {
|
|
509
|
+
return jsonDocument.getMatchingSchemas(schema.schema).filter(function (s) { return !s.inverted; });
|
|
510
|
+
}
|
|
511
|
+
return [];
|
|
512
|
+
});
|
|
513
|
+
};
|
|
514
|
+
return JSONSchemaService;
|
|
515
|
+
}());
|
|
516
|
+
exports.JSONSchemaService = JSONSchemaService;
|
|
517
|
+
var idCounter = 0;
|
|
518
|
+
function normalizeId(id) {
|
|
519
|
+
// remove trailing '#', normalize drive capitalization
|
|
520
|
+
try {
|
|
521
|
+
return vscode_uri_1.URI.parse(id).toString();
|
|
522
|
+
}
|
|
523
|
+
catch (e) {
|
|
524
|
+
return id;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function normalizeResourceForMatching(resource) {
|
|
528
|
+
// remove queries and fragments, normalize drive capitalization
|
|
529
|
+
try {
|
|
530
|
+
return vscode_uri_1.URI.parse(resource).with({ fragment: null, query: null }).toString();
|
|
531
|
+
}
|
|
532
|
+
catch (e) {
|
|
533
|
+
return resource;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
function toDisplayString(url) {
|
|
537
|
+
try {
|
|
538
|
+
var uri = vscode_uri_1.URI.parse(url);
|
|
539
|
+
if (uri.scheme === 'file') {
|
|
540
|
+
return uri.fsPath;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
catch (e) {
|
|
544
|
+
// ignore
|
|
545
|
+
}
|
|
546
|
+
return url;
|
|
547
|
+
}
|
|
548
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
(function (factory) {
|
|
6
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
7
|
+
var v = factory(require, exports);
|
|
8
|
+
if (v !== undefined) module.exports = v;
|
|
9
|
+
}
|
|
10
|
+
else if (typeof define === "function" && define.amd) {
|
|
11
|
+
define(["require", "exports", "../jsonLanguageTypes", "jsonc-parser"], factory);
|
|
12
|
+
}
|
|
13
|
+
})(function (require, exports) {
|
|
14
|
+
"use strict";
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.getSelectionRanges = void 0;
|
|
17
|
+
var jsonLanguageTypes_1 = require("../jsonLanguageTypes");
|
|
18
|
+
var jsonc_parser_1 = require("jsonc-parser");
|
|
19
|
+
function getSelectionRanges(document, positions, doc) {
|
|
20
|
+
function getSelectionRange(position) {
|
|
21
|
+
var offset = document.offsetAt(position);
|
|
22
|
+
var node = doc.getNodeFromOffset(offset, true);
|
|
23
|
+
var result = [];
|
|
24
|
+
while (node) {
|
|
25
|
+
switch (node.type) {
|
|
26
|
+
case 'string':
|
|
27
|
+
case 'object':
|
|
28
|
+
case 'array':
|
|
29
|
+
// range without ", [ or {
|
|
30
|
+
var cStart = node.offset + 1, cEnd = node.offset + node.length - 1;
|
|
31
|
+
if (cStart < cEnd && offset >= cStart && offset <= cEnd) {
|
|
32
|
+
result.push(newRange(cStart, cEnd));
|
|
33
|
+
}
|
|
34
|
+
result.push(newRange(node.offset, node.offset + node.length));
|
|
35
|
+
break;
|
|
36
|
+
case 'number':
|
|
37
|
+
case 'boolean':
|
|
38
|
+
case 'null':
|
|
39
|
+
case 'property':
|
|
40
|
+
result.push(newRange(node.offset, node.offset + node.length));
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
if (node.type === 'property' || node.parent && node.parent.type === 'array') {
|
|
44
|
+
var afterCommaOffset = getOffsetAfterNextToken(node.offset + node.length, 5 /* CommaToken */);
|
|
45
|
+
if (afterCommaOffset !== -1) {
|
|
46
|
+
result.push(newRange(node.offset, afterCommaOffset));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
node = node.parent;
|
|
50
|
+
}
|
|
51
|
+
var current = undefined;
|
|
52
|
+
for (var index = result.length - 1; index >= 0; index--) {
|
|
53
|
+
current = jsonLanguageTypes_1.SelectionRange.create(result[index], current);
|
|
54
|
+
}
|
|
55
|
+
if (!current) {
|
|
56
|
+
current = jsonLanguageTypes_1.SelectionRange.create(jsonLanguageTypes_1.Range.create(position, position));
|
|
57
|
+
}
|
|
58
|
+
return current;
|
|
59
|
+
}
|
|
60
|
+
function newRange(start, end) {
|
|
61
|
+
return jsonLanguageTypes_1.Range.create(document.positionAt(start), document.positionAt(end));
|
|
62
|
+
}
|
|
63
|
+
var scanner = jsonc_parser_1.createScanner(document.getText(), true);
|
|
64
|
+
function getOffsetAfterNextToken(offset, expectedToken) {
|
|
65
|
+
scanner.setPosition(offset);
|
|
66
|
+
var token = scanner.scan();
|
|
67
|
+
if (token === expectedToken) {
|
|
68
|
+
return scanner.getTokenOffset() + scanner.getTokenLength();
|
|
69
|
+
}
|
|
70
|
+
return -1;
|
|
71
|
+
}
|
|
72
|
+
return positions.map(getSelectionRange);
|
|
73
|
+
}
|
|
74
|
+
exports.getSelectionRanges = getSelectionRanges;
|
|
75
|
+
});
|