json.ts ×14

Frontier kind: Code frontier

unlabeled · c_1e6caaf81b82

2403 tests · 3777 LOC · 19 files · introduces 0 tests · 399 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
14 ranges399 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
494 ranges3777 lines · 19 files · Browse complete extent
All tests (intent)
2403 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 399 introduced LOC across 14 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/base/common/json.ts 399 introduced LOC · 14 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- json.ts
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 >
6 > export const enum ScanError {
7 > None = 0,
8 > UnexpectedEndOfComment = 1,
9 > UnexpectedEndOfString = 2,
10 > UnexpectedEndOfNumber = 3,
11 > InvalidUnicode = 4,
12 > InvalidEscapeCharacter = 5,
13 > InvalidCharacter = 6
14 > }
15 >
16 > export const enum SyntaxKind {
17 > OpenBraceToken = 1,
18 > CloseBraceToken = 2,
19 > OpenBracketToken = 3,
20 > CloseBracketToken = 4,
21 > CommaToken = 5,
22 > ColonToken = 6,
23 > NullKeyword = 7,
24 > TrueKeyword = 8,
25 > FalseKeyword = 9,
26 > StringLiteral = 10,
27 > NumericLiteral = 11,
28 > LineCommentTrivia = 12,
29 > BlockCommentTrivia = 13,
30 > LineBreakTrivia = 14,
31 > Trivia = 15,
32 > Unknown = 16,
33 > EOF = 17
34 > }
35 >
36 > /**
37 > * The scanner object, representing a JSON scanner at a position in the input string.
38 > */
39 > export interface JSONScanner {
40 > /**
41 > * Sets the scan position to a new offset. A call to 'scan' is needed to get the first token.
42 > */
43 > setPosition(pos: number): void;
44 > /**
45 > * Read the next token. Returns the token code.
46 > */
47 > scan(): SyntaxKind;
48 > /**
49 > * Returns the current scan position, which is after the last read token.
50 > */
51 > getPosition(): number;
52 > /**
53 > * Returns the last read token.
54 > */
55 > getToken(): SyntaxKind;
56 > /**
57 > * Returns the last read token value. The value for strings is the decoded string content. For numbers its of type number, for boolean it's true or false.
58 > */
59 > getTokenValue(): string;
60 > /**
61 > * The start offset of the last read token.
62 > */
63 > getTokenOffset(): number;
64 > /**
65 > * The length of the last read token.
66 > */
67 > getTokenLength(): number;
68 > /**
69 > * An error code of the last scan.
70 > */
71 > getTokenError(): ScanError;
72 > }
73 >
74 >
75 >
76 > export interface ParseError {
77 > error: ParseErrorCode;
78 > offset: number;
79 > length: number;
80 > }
81 >
82 > export const enum ParseErrorCode {
83 > InvalidSymbol = 1,
84 > InvalidNumberFormat = 2,
85 > PropertyNameExpected = 3,
86 > ValueExpected = 4,
87 > ColonExpected = 5,
88 > CommaExpected = 6,
89 > CloseBraceExpected = 7,
90 > CloseBracketExpected = 8,
91 > EndOfFileExpected = 9,
92 > InvalidCommentToken = 10,
93 > UnexpectedEndOfComment = 11,
94 > UnexpectedEndOfString = 12,
95 > UnexpectedEndOfNumber = 13,
96 > InvalidUnicode = 14,
97 > InvalidEscapeCharacter = 15,
98 > InvalidCharacter = 16
99 > }
100 >
101 > export type NodeType = 'object' | 'array' | 'property' | 'string' | 'number' | 'boolean' | 'null';
102 >
103 > export interface Node {
104 > readonly type: NodeType;
105 > readonly value?: any;
106 > readonly offset: number;
107 > readonly length: number;
108 > readonly colonOffset?: number;
109 > readonly parent?: Node;
110 > readonly children?: Node[];
111 > }
112 >
113 > export type Segment = string | number;
114 > export type JSONPath = Segment[];
115 >
116 > export interface Location {
117 > /**
118 > * The previous property key or literal value (string, number, boolean or null) or undefined.
119 > */
120 > previousNode?: Node;
121 > /**
122 > * The path describing the location in the JSON document. The path consists of a sequence strings
123 > * representing an object property or numbers for array indices.
124 > */
125 > path: JSONPath;
126 > /**
127 > * Matches the locations path against a pattern consisting of strings (for properties) and numbers (for array indices).
128 > * '*' will match a single segment, of any property name or index.
129 > * '**' will match a sequence of segments or no segment, of any property name or index.
130 > */
131 > matches: (patterns: JSONPath) => boolean;
132 > /**
133 > * If set, the location's offset is at a property key.
134 > */
135 > isAtPropertyKey: boolean;
136 > }
137 >
138 > export interface ParseOptions {
139 > disallowComments?: boolean;
140 > allowTrailingComma?: boolean;
141 > allowEmptyContent?: boolean;
142 > }
143 >
144 > export namespace ParseOptions {
145 > export const DEFAULT = {
146 > allowTrailingComma: true
147 > };
148 > }
149 >
150 > export interface JSONVisitor {
151 > /**
152 > * Invoked when an open brace is encountered and an object is started. The offset and length represent the location of the open brace.
153 > */
154 > onObjectBegin?: (offset: number, length: number) => void;
155 >
156 > /**
157 > * Invoked when a property is encountered. The offset and length represent the location of the property name.
158 > */
159 > onObjectProperty?: (property: string, offset: number, length: number) => void;
160 >
161 > /**
162 > * Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace.
163 > */
164 > onObjectEnd?: (offset: number, length: number) => void;
165 >
166 > /**
167 > * Invoked when an open bracket is encountered. The offset and length represent the location of the open bracket.
168 > */
169 > onArrayBegin?: (offset: number, length: number) => void;
170 >
171 > /**
172 > * Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket.
173 > */
174 > onArrayEnd?: (offset: number, length: number) => void;
175 >
176 > /**
177 > * Invoked when a literal value is encountered. The offset and length represent the location of the literal value.
178 > */
179 > onLiteralValue?: (value: any, offset: number, length: number) => void;
180 >
181 > /**
182 > * Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator.
183 > */
184 > onSeparator?: (character: string, offset: number, length: number) => void;
185 >
186 > /**
187 > * When comments are allowed, invoked when a line or block comment is encountered. The offset and length represent the location of the comment.
188 > */
189 > onComment?: (offset: number, length: number) => void;
190 >
191 > /**
192 > * Invoked on an error.
193 > */
194 > onError?: (error: ParseErrorCode, offset: number, length: number) => void;
195 > }
196 >
197 > /**
198 > * Creates a JSON scanner on the given text.
199 > * If ignoreTrivia is set, whitespaces or comments are ignored.
200 > */
201 > export function createScanner(text: string, ignoreTrivia: boolean = false): JSONScanner {
202
203 let pos = 0;
558 };
559 }
560 > json.ts
561 function isWhitespace(ch: number): boolean {
562 return ch === CharacterCodes.space || ch === CharacterCodes.tab || ch === CharacterCodes.verticalTab || ch === CharacterCodes.formFeed ||
564 ch === CharacterCodes.narrowNoBreakSpace || ch === CharacterCodes.mathematicalSpace || ch === CharacterCodes.ideographicSpace || ch === CharacterCodes.byteOrderMark;
565 }
566 > json.ts
567 function isLineBreak(ch: number): boolean {
568 return ch === CharacterCodes.lineFeed || ch === CharacterCodes.carriageReturn || ch === CharacterCodes.lineSeparator || ch === CharacterCodes.paragraphSeparator;
569 }
570 > json.ts
571 function isDigit(ch: number): boolean {
572 return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
573 }
574 > json.ts
575 > const enum CharacterCodes {
576 > nullCharacter = 0,
577 > maxAsciiCharacter = 0x7F,
578 >
579 > lineFeed = 0x0A, // \n
580 > carriageReturn = 0x0D, // \r
581 > lineSeparator = 0x2028,
582 > paragraphSeparator = 0x2029,
583 >
584 > // REVIEW: do we need to support this? The scanner doesn't, but our IText does. This seems
585 > // like an odd disparity? (Or maybe it's completely fine for them to be different).
586 > nextLine = 0x0085,
587 >
588 > // Unicode 3.0 space characters
589 > space = 0x0020, // " "
590 > nonBreakingSpace = 0x00A0, //
591 > enQuad = 0x2000,
592 > emQuad = 0x2001,
593 > enSpace = 0x2002,
594 > emSpace = 0x2003,
595 > threePerEmSpace = 0x2004,
596 > fourPerEmSpace = 0x2005,
597 > sixPerEmSpace = 0x2006,
598 > figureSpace = 0x2007,
599 > punctuationSpace = 0x2008,
600 > thinSpace = 0x2009,
601 > hairSpace = 0x200A,
602 > zeroWidthSpace = 0x200B,
603 > narrowNoBreakSpace = 0x202F,
604 > ideographicSpace = 0x3000,
605 > mathematicalSpace = 0x205F,
606 > ogham = 0x1680,
607 >
608 > _ = 0x5F,
609 > $ = 0x24,
610 >
611 > _0 = 0x30,
612 > _1 = 0x31,
613 > _2 = 0x32,
614 > _3 = 0x33,
615 > _4 = 0x34,
616 > _5 = 0x35,
617 > _6 = 0x36,
618 > _7 = 0x37,
619 > _8 = 0x38,
620 > _9 = 0x39,
621 >
622 > a = 0x61,
623 > b = 0x62,
624 > c = 0x63,
625 > d = 0x64,
626 > e = 0x65,
627 > f = 0x66,
628 > g = 0x67,
629 > h = 0x68,
630 > i = 0x69,
631 > j = 0x6A,
632 > k = 0x6B,
633 > l = 0x6C,
634 > m = 0x6D,
635 > n = 0x6E,
636 > o = 0x6F,
637 > p = 0x70,
638 > q = 0x71,
639 > r = 0x72,
640 > s = 0x73,
641 > t = 0x74,
642 > u = 0x75,
643 > v = 0x76,
644 > w = 0x77,
645 > x = 0x78,
646 > y = 0x79,
647 > z = 0x7A,
648 >
649 > A = 0x41,
650 > B = 0x42,
651 > C = 0x43,
652 > D = 0x44,
653 > E = 0x45,
654 > F = 0x46,
655 > G = 0x47,
656 > H = 0x48,
657 > I = 0x49,
658 > J = 0x4A,
659 > K = 0x4B,
660 > L = 0x4C,
661 > M = 0x4D,
662 > N = 0x4E,
663 > O = 0x4F,
664 > P = 0x50,
665 > Q = 0x51,
666 > R = 0x52,
667 > S = 0x53,
668 > T = 0x54,
669 > U = 0x55,
670 > V = 0x56,
671 > W = 0x57,
672 > X = 0x58,
673 > Y = 0x59,
674 > Z = 0x5A,
675 >
676 > ampersand = 0x26, // &
677 > asterisk = 0x2A, // *
678 > at = 0x40, // @
679 > backslash = 0x5C, // \
680 > bar = 0x7C, // |
681 > caret = 0x5E, // ^
682 > closeBrace = 0x7D, // }
683 > closeBracket = 0x5D, // ]
684 > closeParen = 0x29, // )
685 > colon = 0x3A, // :
686 > comma = 0x2C, // ,
687 > dot = 0x2E, // .
688 > doubleQuote = 0x22, // "
689 > equals = 0x3D, // =
690 > exclamation = 0x21, // !
691 > greaterThan = 0x3E, // >
692 > lessThan = 0x3C, // <
693 > minus = 0x2D, // -
694 > openBrace = 0x7B, // {
695 > openBracket = 0x5B, // [
696 > openParen = 0x28, // (
697 > percent = 0x25, // %
698 > plus = 0x2B, // +
699 > question = 0x3F, // ?
700 > semicolon = 0x3B, // ;
701 > singleQuote = 0x27, // '
702 > slash = 0x2F, // /
703 > tilde = 0x7E, // ~
704 >
705 > backspace = 0x08, // \b
706 > formFeed = 0x0C, // \f
707 > byteOrderMark = 0xFEFF,
708 > tab = 0x09, // \t
709 > verticalTab = 0x0B, // \v
710 > }
711 >
712 > interface NodeImpl extends Node {
713 > type: NodeType;
714 > value?: any;
715 > offset: number;
716 > length: number;
717 > colonOffset?: number;
718 > parent?: NodeImpl;
719 > children?: NodeImpl[];
720 > }
721 >
722 > /**
723 > * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
724 > */
725 > export function getLocation(text: string, position: number): Location {
726 const segments: Segment[] = []; // strings or numbers
727 const earlyReturnException = new Object();
838 };
839 }
840 > json.ts
841 >
842 > /**
843 > * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
844 > * Therefore always check the errors list to find out if the input was valid.
845 > */
846 > export function parse(text: string, errors: ParseError[] = [], options: ParseOptions = ParseOptions.DEFAULT): any {
847 let currentProperty: string | null = null;
848 let currentParent: any = [];
889 return currentParent[0];
890 }
891 > json.ts
892 >
893 > /**
894 > * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
895 > */
896 > export function parseTree(text: string, errors: ParseError[] = [], options: ParseOptions = ParseOptions.DEFAULT): Node {
897 let currentParent: NodeImpl = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root
898
955 return result;
956 }
957 > json.ts
958 > /**
959 > * Finds the node at the given path in a JSON DOM.
960 > */
961 > export function findNodeAtLocation(root: Node, path: JSONPath): Node | undefined {
962 if (!root) {
963 return undefined;
990 return node;
991 }
992 > json.ts
993 > /**
994 > * Gets the JSON path of the given JSON DOM node
995 > */
996 > export function getNodePath(node: Node): JSONPath {
997 if (!node.parent || !node.parent.children) {
998 return [];
1010 return path;
1011 }
1012 > json.ts
1013 > /**
1014 > * Evaluates the JavaScript object of the given JSON DOM node
1015 > */
1016 > export function getNodeValue(node: Node): any {
1017 switch (node.type) {
1018 case 'array':
1038
1039 }
1040 > json.ts
1041 > export function contains(node: Node, offset: number, includeRightBound = false): boolean {
1042 return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));
1043 }
1044 > json.ts
1045 > /**
1046 > * Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
1047 > */
1048 > export function findNodeAtOffset(node: Node, offset: number, includeRightBound = false): Node | undefined {
1049 if (contains(node, offset, includeRightBound)) {
1050 const children = node.children;
1062 return undefined;
1063 }
1064 > json.ts
1065 >
1066 > /**
1067 > * Parses the given text and invokes the visitor functions for each object, array and literal reached.
1068 > */
1069 > export function visit(text: string, visitor: JSONVisitor, options: ParseOptions = ParseOptions.DEFAULT): any {
1070
1071 const _scanner = createScanner(text, false);
1308 return true;
1309 }
1310 > json.ts
1311 > export function getNodeType(value: unknown): NodeType {
1312 switch (typeof value) {
1313 case 'boolean': return 'boolean';