jsonLinks.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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. import { Range } from '../jsonLanguageTypes';
  6. export function findLinks(document, doc) {
  7. var links = [];
  8. doc.visit(function (node) {
  9. var _a;
  10. if (node.type === "property" && node.keyNode.value === "$ref" && ((_a = node.valueNode) === null || _a === void 0 ? void 0 : _a.type) === 'string') {
  11. var path = node.valueNode.value;
  12. var targetNode = findTargetNode(doc, path);
  13. if (targetNode) {
  14. var targetPos = document.positionAt(targetNode.offset);
  15. links.push({
  16. target: document.uri + "#" + (targetPos.line + 1) + "," + (targetPos.character + 1),
  17. range: createRange(document, node.valueNode)
  18. });
  19. }
  20. }
  21. return true;
  22. });
  23. return Promise.resolve(links);
  24. }
  25. function createRange(document, node) {
  26. return Range.create(document.positionAt(node.offset + 1), document.positionAt(node.offset + node.length - 1));
  27. }
  28. function findTargetNode(doc, path) {
  29. var tokens = parseJSONPointer(path);
  30. if (!tokens) {
  31. return null;
  32. }
  33. return findNode(tokens, doc.root);
  34. }
  35. function findNode(pointer, node) {
  36. if (!node) {
  37. return null;
  38. }
  39. if (pointer.length === 0) {
  40. return node;
  41. }
  42. var token = pointer.shift();
  43. if (node && node.type === 'object') {
  44. var propertyNode = node.properties.find(function (propertyNode) { return propertyNode.keyNode.value === token; });
  45. if (!propertyNode) {
  46. return null;
  47. }
  48. return findNode(pointer, propertyNode.valueNode);
  49. }
  50. else if (node && node.type === 'array') {
  51. if (token.match(/^(0|[1-9][0-9]*)$/)) {
  52. var index = Number.parseInt(token);
  53. var arrayItem = node.items[index];
  54. if (!arrayItem) {
  55. return null;
  56. }
  57. return findNode(pointer, arrayItem);
  58. }
  59. }
  60. return null;
  61. }
  62. function parseJSONPointer(path) {
  63. if (path === "#") {
  64. return [];
  65. }
  66. if (path[0] !== '#' || path[1] !== '/') {
  67. return null;
  68. }
  69. return path.substring(2).split(/\//).map(unescape);
  70. }
  71. function unescape(str) {
  72. return str.replace(/~1/g, '/').replace(/~0/g, '~');
  73. }