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.
- package/CHANGELOG.md +10 -1
- package/SECURITY.md +41 -0
- package/lib/esm/jsonLanguageService.js +22 -22
- package/lib/esm/jsonLanguageTypes.d.ts +3 -1
- package/lib/esm/jsonLanguageTypes.js +3 -2
- package/lib/esm/jsonSchema.d.ts +21 -2
- package/lib/esm/parser/jsonParser.js +488 -488
- package/lib/esm/services/configuration.js +9 -9
- package/lib/esm/services/jsonCompletion.js +280 -290
- package/lib/esm/services/jsonDocumentSymbols.js +88 -99
- package/lib/esm/services/jsonFolding.js +38 -39
- package/lib/esm/services/jsonHover.js +40 -43
- package/lib/esm/services/jsonLinks.js +12 -13
- package/lib/esm/services/jsonSchemaService.js +234 -253
- package/lib/esm/services/jsonSelectionRanges.js +9 -9
- package/lib/esm/services/jsonValidation.js +53 -51
- package/lib/esm/utils/colors.js +7 -8
- package/lib/esm/utils/glob.js +12 -12
- package/lib/esm/utils/json.js +7 -7
- package/lib/esm/utils/objects.js +3 -0
- package/lib/esm/utils/strings.js +3 -3
- package/lib/umd/jsonLanguageService.js +36 -32
- package/lib/umd/jsonLanguageTypes.d.ts +3 -1
- package/lib/umd/jsonLanguageTypes.js +5 -3
- package/lib/umd/jsonSchema.d.ts +21 -2
- package/lib/umd/parser/jsonParser.js +492 -482
- package/lib/umd/services/configuration.js +9 -9
- package/lib/umd/services/jsonCompletion.js +287 -296
- package/lib/umd/services/jsonDocumentSymbols.js +92 -102
- package/lib/umd/services/jsonFolding.js +40 -41
- package/lib/umd/services/jsonHover.js +42 -44
- package/lib/umd/services/jsonLinks.js +13 -14
- package/lib/umd/services/jsonSchemaService.js +241 -257
- package/lib/umd/services/jsonSelectionRanges.js +11 -11
- package/lib/umd/services/jsonValidation.js +56 -53
- package/lib/umd/utils/colors.js +7 -8
- package/lib/umd/utils/glob.js +12 -12
- package/lib/umd/utils/json.js +7 -7
- package/lib/umd/utils/objects.js +5 -1
- package/lib/umd/utils/strings.js +3 -3
- package/package.json +12 -12
|
@@ -14,72 +14,68 @@
|
|
|
14
14
|
"use strict";
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.JSONDocumentSymbols = void 0;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
const Parser = require("../parser/jsonParser");
|
|
18
|
+
const Strings = require("../utils/strings");
|
|
19
|
+
const colors_1 = require("../utils/colors");
|
|
20
|
+
const jsonLanguageTypes_1 = require("../jsonLanguageTypes");
|
|
21
|
+
class JSONDocumentSymbols {
|
|
22
|
+
constructor(schemaService) {
|
|
23
23
|
this.schemaService = schemaService;
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (context === void 0) { context = { resultLimit: Number.MAX_VALUE }; }
|
|
28
|
-
var root = doc.root;
|
|
25
|
+
findDocumentSymbols(document, doc, context = { resultLimit: Number.MAX_VALUE }) {
|
|
26
|
+
const root = doc.root;
|
|
29
27
|
if (!root) {
|
|
30
28
|
return [];
|
|
31
29
|
}
|
|
32
|
-
|
|
30
|
+
let limit = context.resultLimit || Number.MAX_VALUE;
|
|
33
31
|
// special handling for key bindings
|
|
34
|
-
|
|
32
|
+
const resourceString = document.uri;
|
|
35
33
|
if ((resourceString === 'vscode://defaultsettings/keybindings.json') || Strings.endsWith(resourceString.toLowerCase(), '/user/keybindings.json')) {
|
|
36
34
|
if (root.type === 'array') {
|
|
37
|
-
|
|
38
|
-
for (
|
|
39
|
-
var item = _a[_i];
|
|
35
|
+
const result = [];
|
|
36
|
+
for (const item of root.items) {
|
|
40
37
|
if (item.type === 'object') {
|
|
41
|
-
for (
|
|
42
|
-
var property = _c[_b];
|
|
38
|
+
for (const property of item.properties) {
|
|
43
39
|
if (property.keyNode.value === 'key' && property.valueNode) {
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
const location = jsonLanguageTypes_1.Location.create(document.uri, getRange(document, item));
|
|
41
|
+
result.push({ name: Parser.getNodeValue(property.valueNode), kind: jsonLanguageTypes_1.SymbolKind.Function, location: location });
|
|
46
42
|
limit--;
|
|
47
43
|
if (limit <= 0) {
|
|
48
44
|
if (context && context.onResultLimitExceeded) {
|
|
49
45
|
context.onResultLimitExceeded(resourceString);
|
|
50
46
|
}
|
|
51
|
-
return
|
|
47
|
+
return result;
|
|
52
48
|
}
|
|
53
49
|
}
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
|
-
return
|
|
53
|
+
return result;
|
|
58
54
|
}
|
|
59
55
|
}
|
|
60
|
-
|
|
56
|
+
const toVisit = [
|
|
61
57
|
{ node: root, containerName: '' }
|
|
62
58
|
];
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
let nextToVisit = 0;
|
|
60
|
+
let limitExceeded = false;
|
|
61
|
+
const result = [];
|
|
62
|
+
const collectOutlineEntries = (node, containerName) => {
|
|
67
63
|
if (node.type === 'array') {
|
|
68
|
-
node.items.forEach(
|
|
64
|
+
node.items.forEach(node => {
|
|
69
65
|
if (node) {
|
|
70
|
-
toVisit.push({ node
|
|
66
|
+
toVisit.push({ node, containerName });
|
|
71
67
|
}
|
|
72
68
|
});
|
|
73
69
|
}
|
|
74
70
|
else if (node.type === 'object') {
|
|
75
|
-
node.properties.forEach(
|
|
76
|
-
|
|
71
|
+
node.properties.forEach((property) => {
|
|
72
|
+
const valueNode = property.valueNode;
|
|
77
73
|
if (valueNode) {
|
|
78
74
|
if (limit > 0) {
|
|
79
75
|
limit--;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
result.push({ name:
|
|
76
|
+
const location = jsonLanguageTypes_1.Location.create(document.uri, getRange(document, property));
|
|
77
|
+
const childContainerName = containerName ? containerName + '.' + property.keyNode.value : property.keyNode.value;
|
|
78
|
+
result.push({ name: this.getKeyLabel(property), kind: this.getSymbolKind(valueNode.type), location: location, containerName: containerName });
|
|
83
79
|
toVisit.push({ node: valueNode, containerName: childContainerName });
|
|
84
80
|
}
|
|
85
81
|
else {
|
|
@@ -91,68 +87,64 @@
|
|
|
91
87
|
};
|
|
92
88
|
// breath first traversal
|
|
93
89
|
while (nextToVisit < toVisit.length) {
|
|
94
|
-
|
|
90
|
+
const next = toVisit[nextToVisit++];
|
|
95
91
|
collectOutlineEntries(next.node, next.containerName);
|
|
96
92
|
}
|
|
97
93
|
if (limitExceeded && context && context.onResultLimitExceeded) {
|
|
98
94
|
context.onResultLimitExceeded(resourceString);
|
|
99
95
|
}
|
|
100
96
|
return result;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (context === void 0) { context = { resultLimit: Number.MAX_VALUE }; }
|
|
105
|
-
var root = doc.root;
|
|
97
|
+
}
|
|
98
|
+
findDocumentSymbols2(document, doc, context = { resultLimit: Number.MAX_VALUE }) {
|
|
99
|
+
const root = doc.root;
|
|
106
100
|
if (!root) {
|
|
107
101
|
return [];
|
|
108
102
|
}
|
|
109
|
-
|
|
103
|
+
let limit = context.resultLimit || Number.MAX_VALUE;
|
|
110
104
|
// special handling for key bindings
|
|
111
|
-
|
|
105
|
+
const resourceString = document.uri;
|
|
112
106
|
if ((resourceString === 'vscode://defaultsettings/keybindings.json') || Strings.endsWith(resourceString.toLowerCase(), '/user/keybindings.json')) {
|
|
113
107
|
if (root.type === 'array') {
|
|
114
|
-
|
|
115
|
-
for (
|
|
116
|
-
var item = _a[_i];
|
|
108
|
+
const result = [];
|
|
109
|
+
for (const item of root.items) {
|
|
117
110
|
if (item.type === 'object') {
|
|
118
|
-
for (
|
|
119
|
-
var property = _c[_b];
|
|
111
|
+
for (const property of item.properties) {
|
|
120
112
|
if (property.keyNode.value === 'key' && property.valueNode) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
113
|
+
const range = getRange(document, item);
|
|
114
|
+
const selectionRange = getRange(document, property.keyNode);
|
|
115
|
+
result.push({ name: Parser.getNodeValue(property.valueNode), kind: jsonLanguageTypes_1.SymbolKind.Function, range, selectionRange });
|
|
124
116
|
limit--;
|
|
125
117
|
if (limit <= 0) {
|
|
126
118
|
if (context && context.onResultLimitExceeded) {
|
|
127
119
|
context.onResultLimitExceeded(resourceString);
|
|
128
120
|
}
|
|
129
|
-
return
|
|
121
|
+
return result;
|
|
130
122
|
}
|
|
131
123
|
}
|
|
132
124
|
}
|
|
133
125
|
}
|
|
134
126
|
}
|
|
135
|
-
return
|
|
127
|
+
return result;
|
|
136
128
|
}
|
|
137
129
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
{ node: root, result
|
|
130
|
+
const result = [];
|
|
131
|
+
const toVisit = [
|
|
132
|
+
{ node: root, result }
|
|
141
133
|
];
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
134
|
+
let nextToVisit = 0;
|
|
135
|
+
let limitExceeded = false;
|
|
136
|
+
const collectOutlineEntries = (node, result) => {
|
|
145
137
|
if (node.type === 'array') {
|
|
146
|
-
node.items.forEach(
|
|
138
|
+
node.items.forEach((node, index) => {
|
|
147
139
|
if (node) {
|
|
148
140
|
if (limit > 0) {
|
|
149
141
|
limit--;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
142
|
+
const range = getRange(document, node);
|
|
143
|
+
const selectionRange = range;
|
|
144
|
+
const name = String(index);
|
|
145
|
+
const symbol = { name, kind: this.getSymbolKind(node.type), range, selectionRange, children: [] };
|
|
154
146
|
result.push(symbol);
|
|
155
|
-
toVisit.push({ result: symbol.children, node
|
|
147
|
+
toVisit.push({ result: symbol.children, node });
|
|
156
148
|
}
|
|
157
149
|
else {
|
|
158
150
|
limitExceeded = true;
|
|
@@ -161,15 +153,15 @@
|
|
|
161
153
|
});
|
|
162
154
|
}
|
|
163
155
|
else if (node.type === 'object') {
|
|
164
|
-
node.properties.forEach(
|
|
165
|
-
|
|
156
|
+
node.properties.forEach((property) => {
|
|
157
|
+
const valueNode = property.valueNode;
|
|
166
158
|
if (valueNode) {
|
|
167
159
|
if (limit > 0) {
|
|
168
160
|
limit--;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
161
|
+
const range = getRange(document, property);
|
|
162
|
+
const selectionRange = getRange(document, property.keyNode);
|
|
163
|
+
const children = [];
|
|
164
|
+
const symbol = { name: this.getKeyLabel(property), kind: this.getSymbolKind(valueNode.type), range, selectionRange, children, detail: this.getDetail(valueNode) };
|
|
173
165
|
result.push(symbol);
|
|
174
166
|
toVisit.push({ result: children, node: valueNode });
|
|
175
167
|
}
|
|
@@ -182,15 +174,15 @@
|
|
|
182
174
|
};
|
|
183
175
|
// breath first traversal
|
|
184
176
|
while (nextToVisit < toVisit.length) {
|
|
185
|
-
|
|
177
|
+
const next = toVisit[nextToVisit++];
|
|
186
178
|
collectOutlineEntries(next.node, next.result);
|
|
187
179
|
}
|
|
188
180
|
if (limitExceeded && context && context.onResultLimitExceeded) {
|
|
189
181
|
context.onResultLimitExceeded(resourceString);
|
|
190
182
|
}
|
|
191
183
|
return result;
|
|
192
|
-
}
|
|
193
|
-
|
|
184
|
+
}
|
|
185
|
+
getSymbolKind(nodeType) {
|
|
194
186
|
switch (nodeType) {
|
|
195
187
|
case 'object':
|
|
196
188
|
return jsonLanguageTypes_1.SymbolKind.Module;
|
|
@@ -205,18 +197,18 @@
|
|
|
205
197
|
default: // 'null'
|
|
206
198
|
return jsonLanguageTypes_1.SymbolKind.Variable;
|
|
207
199
|
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
}
|
|
201
|
+
getKeyLabel(property) {
|
|
202
|
+
let name = property.keyNode.value;
|
|
211
203
|
if (name) {
|
|
212
204
|
name = name.replace(/[\n]/g, '↵');
|
|
213
205
|
}
|
|
214
206
|
if (name && name.trim()) {
|
|
215
207
|
return name;
|
|
216
208
|
}
|
|
217
|
-
return "
|
|
218
|
-
}
|
|
219
|
-
|
|
209
|
+
return `"${name}"`;
|
|
210
|
+
}
|
|
211
|
+
getDetail(node) {
|
|
220
212
|
if (!node) {
|
|
221
213
|
return undefined;
|
|
222
214
|
}
|
|
@@ -232,23 +224,22 @@
|
|
|
232
224
|
}
|
|
233
225
|
}
|
|
234
226
|
return undefined;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return this.schemaService.getSchemaForResource(document.uri, doc).then(
|
|
238
|
-
|
|
227
|
+
}
|
|
228
|
+
findDocumentColors(document, doc, context) {
|
|
229
|
+
return this.schemaService.getSchemaForResource(document.uri, doc).then(schema => {
|
|
230
|
+
const result = [];
|
|
239
231
|
if (schema) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
for (
|
|
244
|
-
var s = matchingSchemas_1[_i];
|
|
232
|
+
let limit = context && typeof context.resultLimit === 'number' ? context.resultLimit : Number.MAX_VALUE;
|
|
233
|
+
const matchingSchemas = doc.getMatchingSchemas(schema.schema);
|
|
234
|
+
const visitedNode = {};
|
|
235
|
+
for (const s of matchingSchemas) {
|
|
245
236
|
if (!s.inverted && s.schema && (s.schema.format === 'color' || s.schema.format === 'color-hex') && s.node && s.node.type === 'string') {
|
|
246
|
-
|
|
237
|
+
const nodeId = String(s.node.offset);
|
|
247
238
|
if (!visitedNode[nodeId]) {
|
|
248
|
-
|
|
239
|
+
const color = (0, colors_1.colorFromHex)(Parser.getNodeValue(s.node));
|
|
249
240
|
if (color) {
|
|
250
|
-
|
|
251
|
-
result.push({ color
|
|
241
|
+
const range = getRange(document, s.node);
|
|
242
|
+
result.push({ color, range });
|
|
252
243
|
}
|
|
253
244
|
visitedNode[nodeId] = true;
|
|
254
245
|
limit--;
|
|
@@ -264,26 +255,25 @@
|
|
|
264
255
|
}
|
|
265
256
|
return result;
|
|
266
257
|
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
258
|
+
}
|
|
259
|
+
getColorPresentations(document, doc, color, range) {
|
|
260
|
+
const result = [];
|
|
261
|
+
const red256 = Math.round(color.red * 255), green256 = Math.round(color.green * 255), blue256 = Math.round(color.blue * 255);
|
|
271
262
|
function toTwoDigitHex(n) {
|
|
272
|
-
|
|
263
|
+
const r = n.toString(16);
|
|
273
264
|
return r.length !== 2 ? '0' + r : r;
|
|
274
265
|
}
|
|
275
|
-
|
|
266
|
+
let label;
|
|
276
267
|
if (color.alpha === 1) {
|
|
277
|
-
label =
|
|
268
|
+
label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}`;
|
|
278
269
|
}
|
|
279
270
|
else {
|
|
280
|
-
label =
|
|
271
|
+
label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}${toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
|
281
272
|
}
|
|
282
273
|
result.push({ label: label, textEdit: jsonLanguageTypes_1.TextEdit.replace(range, JSON.stringify(label)) });
|
|
283
274
|
return result;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
}());
|
|
275
|
+
}
|
|
276
|
+
}
|
|
287
277
|
exports.JSONDocumentSymbols = JSONDocumentSymbols;
|
|
288
278
|
function getRange(document, node) {
|
|
289
279
|
return jsonLanguageTypes_1.Range.create(document.positionAt(node.offset), document.positionAt(node.offset + node.length));
|
|
@@ -14,34 +14,34 @@
|
|
|
14
14
|
"use strict";
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.getFoldingRanges = void 0;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const jsonc_parser_1 = require("jsonc-parser");
|
|
18
|
+
const jsonLanguageTypes_1 = require("../jsonLanguageTypes");
|
|
19
19
|
function getFoldingRanges(document, context) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
const ranges = [];
|
|
21
|
+
const nestingLevels = [];
|
|
22
|
+
const stack = [];
|
|
23
|
+
let prevStart = -1;
|
|
24
|
+
const scanner = (0, jsonc_parser_1.createScanner)(document.getText(), false);
|
|
25
|
+
let token = scanner.scan();
|
|
26
26
|
function addRange(range) {
|
|
27
27
|
ranges.push(range);
|
|
28
28
|
nestingLevels.push(stack.length);
|
|
29
29
|
}
|
|
30
|
-
while (token !== 17 /* EOF */) {
|
|
30
|
+
while (token !== 17 /* SyntaxKind.EOF */) {
|
|
31
31
|
switch (token) {
|
|
32
|
-
case 1 /* OpenBraceToken */:
|
|
33
|
-
case 3 /* OpenBracketToken */: {
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
case 1 /* SyntaxKind.OpenBraceToken */:
|
|
33
|
+
case 3 /* SyntaxKind.OpenBracketToken */: {
|
|
34
|
+
const startLine = document.positionAt(scanner.getTokenOffset()).line;
|
|
35
|
+
const range = { startLine, endLine: startLine, kind: token === 1 /* SyntaxKind.OpenBraceToken */ ? 'object' : 'array' };
|
|
36
36
|
stack.push(range);
|
|
37
37
|
break;
|
|
38
38
|
}
|
|
39
|
-
case 2 /* CloseBraceToken */:
|
|
40
|
-
case 4 /* CloseBracketToken */: {
|
|
41
|
-
|
|
39
|
+
case 2 /* SyntaxKind.CloseBraceToken */:
|
|
40
|
+
case 4 /* SyntaxKind.CloseBracketToken */: {
|
|
41
|
+
const kind = token === 2 /* SyntaxKind.CloseBraceToken */ ? 'object' : 'array';
|
|
42
42
|
if (stack.length > 0 && stack[stack.length - 1].kind === kind) {
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const range = stack.pop();
|
|
44
|
+
const line = document.positionAt(scanner.getTokenOffset()).line;
|
|
45
45
|
if (range && line > range.startLine + 1 && prevStart !== range.startLine) {
|
|
46
46
|
range.endLine = line - 1;
|
|
47
47
|
addRange(range);
|
|
@@ -50,36 +50,36 @@
|
|
|
50
50
|
}
|
|
51
51
|
break;
|
|
52
52
|
}
|
|
53
|
-
case 13 /* BlockCommentTrivia */: {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (scanner.getTokenError() === 1 /* UnexpectedEndOfComment */ && startLine + 1 < document.lineCount) {
|
|
53
|
+
case 13 /* SyntaxKind.BlockCommentTrivia */: {
|
|
54
|
+
const startLine = document.positionAt(scanner.getTokenOffset()).line;
|
|
55
|
+
const endLine = document.positionAt(scanner.getTokenOffset() + scanner.getTokenLength()).line;
|
|
56
|
+
if (scanner.getTokenError() === 1 /* ScanError.UnexpectedEndOfComment */ && startLine + 1 < document.lineCount) {
|
|
57
57
|
scanner.setPosition(document.offsetAt(jsonLanguageTypes_1.Position.create(startLine + 1, 0)));
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
60
60
|
if (startLine < endLine) {
|
|
61
|
-
addRange({ startLine
|
|
61
|
+
addRange({ startLine, endLine, kind: jsonLanguageTypes_1.FoldingRangeKind.Comment });
|
|
62
62
|
prevStart = startLine;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
break;
|
|
66
66
|
}
|
|
67
|
-
case 12 /* LineCommentTrivia */: {
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
case 12 /* SyntaxKind.LineCommentTrivia */: {
|
|
68
|
+
const text = document.getText().substr(scanner.getTokenOffset(), scanner.getTokenLength());
|
|
69
|
+
const m = text.match(/^\/\/\s*#(region\b)|(endregion\b)/);
|
|
70
70
|
if (m) {
|
|
71
|
-
|
|
71
|
+
const line = document.positionAt(scanner.getTokenOffset()).line;
|
|
72
72
|
if (m[1]) { // start pattern match
|
|
73
|
-
|
|
73
|
+
const range = { startLine: line, endLine: line, kind: jsonLanguageTypes_1.FoldingRangeKind.Region };
|
|
74
74
|
stack.push(range);
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
|
-
|
|
77
|
+
let i = stack.length - 1;
|
|
78
78
|
while (i >= 0 && stack[i].kind !== jsonLanguageTypes_1.FoldingRangeKind.Region) {
|
|
79
79
|
i--;
|
|
80
80
|
}
|
|
81
81
|
if (i >= 0) {
|
|
82
|
-
|
|
82
|
+
const range = stack[i];
|
|
83
83
|
stack.length = i;
|
|
84
84
|
if (line > range.startLine && prevStart !== range.startLine) {
|
|
85
85
|
range.endLine = line;
|
|
@@ -94,24 +94,23 @@
|
|
|
94
94
|
}
|
|
95
95
|
token = scanner.scan();
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
const rangeLimit = context && context.rangeLimit;
|
|
98
98
|
if (typeof rangeLimit !== 'number' || ranges.length <= rangeLimit) {
|
|
99
99
|
return ranges;
|
|
100
100
|
}
|
|
101
101
|
if (context && context.onRangeLimitExceeded) {
|
|
102
102
|
context.onRangeLimitExceeded(document.uri);
|
|
103
103
|
}
|
|
104
|
-
|
|
105
|
-
for (
|
|
106
|
-
var level = nestingLevels_1[_i];
|
|
104
|
+
const counts = [];
|
|
105
|
+
for (let level of nestingLevels) {
|
|
107
106
|
if (level < 30) {
|
|
108
107
|
counts[level] = (counts[level] || 0) + 1;
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
for (
|
|
114
|
-
|
|
110
|
+
let entries = 0;
|
|
111
|
+
let maxLevel = 0;
|
|
112
|
+
for (let i = 0; i < counts.length; i++) {
|
|
113
|
+
const n = counts[i];
|
|
115
114
|
if (n) {
|
|
116
115
|
if (n + entries > rangeLimit) {
|
|
117
116
|
maxLevel = i;
|
|
@@ -120,9 +119,9 @@
|
|
|
120
119
|
entries += n;
|
|
121
120
|
}
|
|
122
121
|
}
|
|
123
|
-
|
|
124
|
-
for (
|
|
125
|
-
|
|
122
|
+
const result = [];
|
|
123
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
124
|
+
const level = nestingLevels[i];
|
|
126
125
|
if (typeof level === 'number') {
|
|
127
126
|
if (level < maxLevel || (level === maxLevel && entries++ < rangeLimit)) {
|
|
128
127
|
result.push(ranges[i]);
|
|
@@ -14,25 +14,24 @@
|
|
|
14
14
|
"use strict";
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.JSONHover = void 0;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (contributions === void 0) { contributions = []; }
|
|
17
|
+
const Parser = require("../parser/jsonParser");
|
|
18
|
+
const jsonLanguageTypes_1 = require("../jsonLanguageTypes");
|
|
19
|
+
class JSONHover {
|
|
20
|
+
constructor(schemaService, contributions = [], promiseConstructor) {
|
|
22
21
|
this.schemaService = schemaService;
|
|
23
22
|
this.contributions = contributions;
|
|
24
23
|
this.promise = promiseConstructor || Promise;
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
doHover(document, position, doc) {
|
|
26
|
+
const offset = document.offsetAt(position);
|
|
27
|
+
let node = doc.getNodeFromOffset(offset);
|
|
29
28
|
if (!node || (node.type === 'object' || node.type === 'array') && offset > node.offset + 1 && offset < node.offset + node.length - 1) {
|
|
30
29
|
return this.promise.resolve(null);
|
|
31
30
|
}
|
|
32
|
-
|
|
31
|
+
const hoverRangeNode = node;
|
|
33
32
|
// use the property description when hovering over an object key
|
|
34
33
|
if (node.type === 'string') {
|
|
35
|
-
|
|
34
|
+
const parent = node.parent;
|
|
36
35
|
if (parent && parent.type === 'property' && parent.keyNode === node) {
|
|
37
36
|
node = parent.valueNode;
|
|
38
37
|
if (!node) {
|
|
@@ -40,77 +39,76 @@
|
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
|
-
|
|
44
|
-
var createHover =
|
|
45
|
-
|
|
42
|
+
const hoverRange = jsonLanguageTypes_1.Range.create(document.positionAt(hoverRangeNode.offset), document.positionAt(hoverRangeNode.offset + hoverRangeNode.length));
|
|
43
|
+
var createHover = (contents) => {
|
|
44
|
+
const result = {
|
|
46
45
|
contents: contents,
|
|
47
46
|
range: hoverRange
|
|
48
47
|
};
|
|
49
48
|
return result;
|
|
50
49
|
};
|
|
51
|
-
|
|
52
|
-
for (
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
const location = Parser.getNodePath(node);
|
|
51
|
+
for (let i = this.contributions.length - 1; i >= 0; i--) {
|
|
52
|
+
const contribution = this.contributions[i];
|
|
53
|
+
const promise = contribution.getInfoContribution(document.uri, location);
|
|
55
54
|
if (promise) {
|
|
56
|
-
return promise.then(
|
|
55
|
+
return promise.then(htmlContent => createHover(htmlContent));
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
|
-
return this.schemaService.getSchemaForResource(document.uri, doc).then(
|
|
58
|
+
return this.schemaService.getSchemaForResource(document.uri, doc).then((schema) => {
|
|
60
59
|
if (schema && node) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
matchingSchemas.every(
|
|
60
|
+
const matchingSchemas = doc.getMatchingSchemas(schema.schema, node.offset);
|
|
61
|
+
let title = undefined;
|
|
62
|
+
let markdownDescription = undefined;
|
|
63
|
+
let markdownEnumValueDescription = undefined, enumValue = undefined;
|
|
64
|
+
matchingSchemas.every((s) => {
|
|
66
65
|
if (s.node === node && !s.inverted && s.schema) {
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
title = title || s.schema.title;
|
|
67
|
+
markdownDescription = markdownDescription || s.schema.markdownDescription || toMarkdown(s.schema.description);
|
|
69
68
|
if (s.schema.enum) {
|
|
70
|
-
|
|
69
|
+
const idx = s.schema.enum.indexOf(Parser.getNodeValue(node));
|
|
71
70
|
if (s.schema.markdownEnumDescriptions) {
|
|
72
|
-
|
|
71
|
+
markdownEnumValueDescription = s.schema.markdownEnumDescriptions[idx];
|
|
73
72
|
}
|
|
74
73
|
else if (s.schema.enumDescriptions) {
|
|
75
|
-
|
|
74
|
+
markdownEnumValueDescription = toMarkdown(s.schema.enumDescriptions[idx]);
|
|
76
75
|
}
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
if (typeof
|
|
80
|
-
|
|
76
|
+
if (markdownEnumValueDescription) {
|
|
77
|
+
enumValue = s.schema.enum[idx];
|
|
78
|
+
if (typeof enumValue !== 'string') {
|
|
79
|
+
enumValue = JSON.stringify(enumValue);
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
return true;
|
|
86
85
|
});
|
|
87
|
-
|
|
88
|
-
if (
|
|
89
|
-
result = toMarkdown(
|
|
86
|
+
let result = '';
|
|
87
|
+
if (title) {
|
|
88
|
+
result = toMarkdown(title);
|
|
90
89
|
}
|
|
91
|
-
if (
|
|
90
|
+
if (markdownDescription) {
|
|
92
91
|
if (result.length > 0) {
|
|
93
92
|
result += "\n\n";
|
|
94
93
|
}
|
|
95
|
-
result +=
|
|
94
|
+
result += markdownDescription;
|
|
96
95
|
}
|
|
97
|
-
if (
|
|
96
|
+
if (markdownEnumValueDescription) {
|
|
98
97
|
if (result.length > 0) {
|
|
99
98
|
result += "\n\n";
|
|
100
99
|
}
|
|
101
|
-
result +=
|
|
100
|
+
result += `\`${toMarkdownCodeBlock(enumValue)}\`: ${markdownEnumValueDescription}`;
|
|
102
101
|
}
|
|
103
102
|
return createHover([result]);
|
|
104
103
|
}
|
|
105
104
|
return null;
|
|
106
105
|
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
}());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
110
108
|
exports.JSONHover = JSONHover;
|
|
111
109
|
function toMarkdown(plain) {
|
|
112
110
|
if (plain) {
|
|
113
|
-
|
|
111
|
+
const res = plain.replace(/([^\n\r])(\r?\n)([^\n\r])/gm, '$1\n\n$3'); // single new lines to \n\n (Markdown paragraph)
|
|
114
112
|
return res.replace(/[\\`*_{}[\]()#+\-.!]/g, "\\$&"); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
|
|
115
113
|
}
|
|
116
114
|
return undefined;
|