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