123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import * as Parser from '../parser/jsonParser';
- import * as Strings from '../utils/strings';
- import { colorFromHex } from '../utils/colors';
- import { Range, TextEdit, SymbolKind, Location } from "../jsonLanguageTypes";
- var JSONDocumentSymbols = /** @class */ (function () {
- function JSONDocumentSymbols(schemaService) {
- this.schemaService = schemaService;
- }
- JSONDocumentSymbols.prototype.findDocumentSymbols = function (document, doc, context) {
- var _this = this;
- if (context === void 0) { context = { resultLimit: Number.MAX_VALUE }; }
- var root = doc.root;
- if (!root) {
- return [];
- }
- var limit = context.resultLimit || Number.MAX_VALUE;
- // special handling for key bindings
- var resourceString = document.uri;
- if ((resourceString === 'vscode://defaultsettings/keybindings.json') || Strings.endsWith(resourceString.toLowerCase(), '/user/keybindings.json')) {
- if (root.type === 'array') {
- var result_1 = [];
- for (var _i = 0, _a = root.items; _i < _a.length; _i++) {
- var item = _a[_i];
- if (item.type === 'object') {
- for (var _b = 0, _c = item.properties; _b < _c.length; _b++) {
- var property = _c[_b];
- if (property.keyNode.value === 'key' && property.valueNode) {
- var location = Location.create(document.uri, getRange(document, item));
- result_1.push({ name: Parser.getNodeValue(property.valueNode), kind: SymbolKind.Function, location: location });
- limit--;
- if (limit <= 0) {
- if (context && context.onResultLimitExceeded) {
- context.onResultLimitExceeded(resourceString);
- }
- return result_1;
- }
- }
- }
- }
- }
- return result_1;
- }
- }
- var toVisit = [
- { node: root, containerName: '' }
- ];
- var nextToVisit = 0;
- var limitExceeded = false;
- var result = [];
- var collectOutlineEntries = function (node, containerName) {
- if (node.type === 'array') {
- node.items.forEach(function (node) {
- if (node) {
- toVisit.push({ node: node, containerName: containerName });
- }
- });
- }
- else if (node.type === 'object') {
- node.properties.forEach(function (property) {
- var valueNode = property.valueNode;
- if (valueNode) {
- if (limit > 0) {
- limit--;
- var location = Location.create(document.uri, getRange(document, property));
- var childContainerName = containerName ? containerName + '.' + property.keyNode.value : property.keyNode.value;
- result.push({ name: _this.getKeyLabel(property), kind: _this.getSymbolKind(valueNode.type), location: location, containerName: containerName });
- toVisit.push({ node: valueNode, containerName: childContainerName });
- }
- else {
- limitExceeded = true;
- }
- }
- });
- }
- };
- // breath first traversal
- while (nextToVisit < toVisit.length) {
- var next = toVisit[nextToVisit++];
- collectOutlineEntries(next.node, next.containerName);
- }
- if (limitExceeded && context && context.onResultLimitExceeded) {
- context.onResultLimitExceeded(resourceString);
- }
- return result;
- };
- JSONDocumentSymbols.prototype.findDocumentSymbols2 = function (document, doc, context) {
- var _this = this;
- if (context === void 0) { context = { resultLimit: Number.MAX_VALUE }; }
- var root = doc.root;
- if (!root) {
- return [];
- }
- var limit = context.resultLimit || Number.MAX_VALUE;
- // special handling for key bindings
- var resourceString = document.uri;
- if ((resourceString === 'vscode://defaultsettings/keybindings.json') || Strings.endsWith(resourceString.toLowerCase(), '/user/keybindings.json')) {
- if (root.type === 'array') {
- var result_2 = [];
- for (var _i = 0, _a = root.items; _i < _a.length; _i++) {
- var item = _a[_i];
- if (item.type === 'object') {
- for (var _b = 0, _c = item.properties; _b < _c.length; _b++) {
- var property = _c[_b];
- if (property.keyNode.value === 'key' && property.valueNode) {
- var range = getRange(document, item);
- var selectionRange = getRange(document, property.keyNode);
- result_2.push({ name: Parser.getNodeValue(property.valueNode), kind: SymbolKind.Function, range: range, selectionRange: selectionRange });
- limit--;
- if (limit <= 0) {
- if (context && context.onResultLimitExceeded) {
- context.onResultLimitExceeded(resourceString);
- }
- return result_2;
- }
- }
- }
- }
- }
- return result_2;
- }
- }
- var result = [];
- var toVisit = [
- { node: root, result: result }
- ];
- var nextToVisit = 0;
- var limitExceeded = false;
- var collectOutlineEntries = function (node, result) {
- if (node.type === 'array') {
- node.items.forEach(function (node, index) {
- if (node) {
- if (limit > 0) {
- limit--;
- var range = getRange(document, node);
- var selectionRange = range;
- var name = String(index);
- var symbol = { name: name, kind: _this.getSymbolKind(node.type), range: range, selectionRange: selectionRange, children: [] };
- result.push(symbol);
- toVisit.push({ result: symbol.children, node: node });
- }
- else {
- limitExceeded = true;
- }
- }
- });
- }
- else if (node.type === 'object') {
- node.properties.forEach(function (property) {
- var valueNode = property.valueNode;
- if (valueNode) {
- if (limit > 0) {
- limit--;
- var range = getRange(document, property);
- var selectionRange = getRange(document, property.keyNode);
- var children = [];
- var symbol = { name: _this.getKeyLabel(property), kind: _this.getSymbolKind(valueNode.type), range: range, selectionRange: selectionRange, children: children, detail: _this.getDetail(valueNode) };
- result.push(symbol);
- toVisit.push({ result: children, node: valueNode });
- }
- else {
- limitExceeded = true;
- }
- }
- });
- }
- };
- // breath first traversal
- while (nextToVisit < toVisit.length) {
- var next = toVisit[nextToVisit++];
- collectOutlineEntries(next.node, next.result);
- }
- if (limitExceeded && context && context.onResultLimitExceeded) {
- context.onResultLimitExceeded(resourceString);
- }
- return result;
- };
- JSONDocumentSymbols.prototype.getSymbolKind = function (nodeType) {
- switch (nodeType) {
- case 'object':
- return SymbolKind.Module;
- case 'string':
- return SymbolKind.String;
- case 'number':
- return SymbolKind.Number;
- case 'array':
- return SymbolKind.Array;
- case 'boolean':
- return SymbolKind.Boolean;
- default: // 'null'
- return SymbolKind.Variable;
- }
- };
- JSONDocumentSymbols.prototype.getKeyLabel = function (property) {
- var name = property.keyNode.value;
- if (name) {
- name = name.replace(/[\n]/g, '↵');
- }
- if (name && name.trim()) {
- return name;
- }
- return "\"" + name + "\"";
- };
- JSONDocumentSymbols.prototype.getDetail = function (node) {
- if (!node) {
- return undefined;
- }
- if (node.type === 'boolean' || node.type === 'number' || node.type === 'null' || node.type === 'string') {
- return String(node.value);
- }
- else {
- if (node.type === 'array') {
- return node.children.length ? undefined : '[]';
- }
- else if (node.type === 'object') {
- return node.children.length ? undefined : '{}';
- }
- }
- return undefined;
- };
- JSONDocumentSymbols.prototype.findDocumentColors = function (document, doc, context) {
- return this.schemaService.getSchemaForResource(document.uri, doc).then(function (schema) {
- var result = [];
- if (schema) {
- var limit = context && typeof context.resultLimit === 'number' ? context.resultLimit : Number.MAX_VALUE;
- var matchingSchemas = doc.getMatchingSchemas(schema.schema);
- var visitedNode = {};
- for (var _i = 0, matchingSchemas_1 = matchingSchemas; _i < matchingSchemas_1.length; _i++) {
- var s = matchingSchemas_1[_i];
- if (!s.inverted && s.schema && (s.schema.format === 'color' || s.schema.format === 'color-hex') && s.node && s.node.type === 'string') {
- var nodeId = String(s.node.offset);
- if (!visitedNode[nodeId]) {
- var color = colorFromHex(Parser.getNodeValue(s.node));
- if (color) {
- var range = getRange(document, s.node);
- result.push({ color: color, range: range });
- }
- visitedNode[nodeId] = true;
- limit--;
- if (limit <= 0) {
- if (context && context.onResultLimitExceeded) {
- context.onResultLimitExceeded(document.uri);
- }
- return result;
- }
- }
- }
- }
- }
- return result;
- });
- };
- JSONDocumentSymbols.prototype.getColorPresentations = function (document, doc, color, range) {
- var result = [];
- var red256 = Math.round(color.red * 255), green256 = Math.round(color.green * 255), blue256 = Math.round(color.blue * 255);
- function toTwoDigitHex(n) {
- var r = n.toString(16);
- return r.length !== 2 ? '0' + r : r;
- }
- var label;
- if (color.alpha === 1) {
- label = "#" + toTwoDigitHex(red256) + toTwoDigitHex(green256) + toTwoDigitHex(blue256);
- }
- else {
- label = "#" + toTwoDigitHex(red256) + toTwoDigitHex(green256) + toTwoDigitHex(blue256) + toTwoDigitHex(Math.round(color.alpha * 255));
- }
- result.push({ label: label, textEdit: TextEdit.replace(range, JSON.stringify(label)) });
- return result;
- };
- return JSONDocumentSymbols;
- }());
- export { JSONDocumentSymbols };
- function getRange(document, node) {
- return Range.create(document.positionAt(node.offset), document.positionAt(node.offset + node.length));
- }
|