@speclynx/apidom-parser-adapter-json 1.12.2 → 2.0.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/NOTICE +16 -7
  3. package/README.md +36 -25
  4. package/dist/167.apidom-parser-adapter-json.browser.min.js +1 -1
  5. package/dist/451.apidom-parser-adapter-json.browser.min.js +1 -1
  6. package/dist/apidom-parser-adapter-json.browser.js +3101 -12890
  7. package/dist/apidom-parser-adapter-json.browser.min.js +1 -1
  8. package/package.json +7 -11
  9. package/src/adapter.cjs +29 -34
  10. package/src/adapter.mjs +26 -31
  11. package/src/native/index.cjs +30 -0
  12. package/src/native/index.mjs +25 -0
  13. package/src/tree-sitter/index.cjs +54 -0
  14. package/src/tree-sitter/index.mjs +48 -0
  15. package/src/{lexical-analysis → tree-sitter/lexical-analysis}/index.cjs +1 -1
  16. package/src/{lexical-analysis → tree-sitter/lexical-analysis}/index.mjs +1 -1
  17. package/src/tree-sitter/syntactic-analysis/index.cjs +223 -0
  18. package/src/tree-sitter/syntactic-analysis/index.mjs +219 -0
  19. package/types/apidom-parser-adapter-json.d.ts +14 -33
  20. package/src/syntactic-analysis/TreeCursorIterator.cjs +0 -62
  21. package/src/syntactic-analysis/TreeCursorIterator.mjs +0 -57
  22. package/src/syntactic-analysis/TreeCursorSyntaxNode.cjs +0 -51
  23. package/src/syntactic-analysis/TreeCursorSyntaxNode.mjs +0 -47
  24. package/src/syntactic-analysis/direct/index.cjs +0 -64
  25. package/src/syntactic-analysis/direct/index.mjs +0 -59
  26. package/src/syntactic-analysis/direct/visitors/CstVisitor.cjs +0 -163
  27. package/src/syntactic-analysis/direct/visitors/CstVisitor.mjs +0 -158
  28. package/src/syntactic-analysis/indirect/index.cjs +0 -56
  29. package/src/syntactic-analysis/indirect/index.mjs +0 -49
  30. package/src/syntactic-analysis/indirect/visitors/CstVisitor.cjs +0 -177
  31. package/src/syntactic-analysis/indirect/visitors/CstVisitor.mjs +0 -172
  32. package/src/syntactic-analysis/indirect/visitors/JsonAstVisitor.cjs +0 -189
  33. package/src/syntactic-analysis/indirect/visitors/JsonAstVisitor.mjs +0 -183
@@ -1,47 +0,0 @@
1
- class TreeCursorSyntaxNode {
2
- type;
3
- startPosition;
4
- endPosition;
5
- startIndex;
6
- endIndex;
7
- text;
8
- isNamed;
9
- isMissing;
10
- fieldName = null;
11
- hasError = false;
12
- children = [];
13
- constructor(cursor) {
14
- this.type = cursor.nodeType;
15
- this.startPosition = cursor.startPosition;
16
- this.endPosition = cursor.endPosition;
17
- this.startIndex = cursor.startIndex;
18
- this.endIndex = cursor.endIndex;
19
- this.text = cursor.nodeText;
20
- this.isNamed = cursor.nodeIsNamed;
21
- this.isMissing = cursor.nodeIsMissing;
22
- }
23
- get keyNode() {
24
- if (this.type === 'pair') {
25
- return this.children.find(node => node.fieldName === 'key');
26
- }
27
- return undefined;
28
- }
29
- get valueNode() {
30
- if (this.type === 'pair') {
31
- return this.children.find(node => node.fieldName === 'value');
32
- }
33
- return undefined;
34
- }
35
- setFieldName(cursor) {
36
- this.fieldName = cursor.currentFieldName;
37
- return this;
38
- }
39
- setHasError(cursor) {
40
- this.hasError = cursor.currentNode.hasError;
41
- return this;
42
- }
43
- pushChildren(...children) {
44
- this.children.push(...children);
45
- }
46
- }
47
- export default TreeCursorSyntaxNode;
@@ -1,64 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
- exports.__esModule = true;
5
- exports.default = void 0;
6
- var _apidomAst = require("@speclynx/apidom-ast");
7
- var _apidomCore = require("@speclynx/apidom-core");
8
- var _CstVisitor = _interopRequireDefault(require("./visitors/CstVisitor.cjs"));
9
- var _TreeCursorIterator = _interopRequireDefault(require("../TreeCursorIterator.cjs"));
10
- const keyMap = {
11
- document: ['children'],
12
- object: ['children'],
13
- array: ['children'],
14
- string: ['children'],
15
- property: ['children'],
16
- key: ['children'],
17
- error: ['children'],
18
- ..._apidomCore.keyMap
19
- };
20
- const getNodeType = node => {
21
- if ((0, _apidomCore.isParseResultElement)(node)) {
22
- return 'ParseResultElement';
23
- }
24
- if ((0, _apidomCore.isElement)(node)) {
25
- return (0, _apidomCore.getNodeType)(node);
26
- }
27
- return (0, _apidomAst.getNodeType)(node);
28
- };
29
-
30
- // @ts-ignore
31
- const isNode = element => (0, _apidomCore.isElement)(element) || (0, _apidomAst.isNode)(element);
32
-
33
- /**
34
- * This version of syntactic analysis translates TreeSitter CTS
35
- * directly into ApiDOM.
36
- *
37
- * Transient transformation of TreeSitter CST is performed
38
- * using TreeSitter cursor. TreeSitter cursor is a stateful object
39
- * that allows us to walk syntax tree containing large number of nodes
40
- * with maximum efficiency. Using this transient CST transformation
41
- * gives us double the performance when syntactically analyzing
42
- * CST into ApiDOM.
43
- *
44
- * Single traversal pass is needed to get from CST to ApiDOM.
45
- * @public
46
- */
47
- const analyze = (cst, {
48
- sourceMap = false
49
- } = {}) => {
50
- const visitor = new _CstVisitor.default();
51
- const cursor = cst.walk();
52
- const iterator = new _TreeCursorIterator.default(cursor);
53
- const [rootNode] = Array.from(iterator);
54
- return (0, _apidomAst.visit)(rootNode, visitor, {
55
- // @ts-ignore
56
- keyMap,
57
- nodeTypeGetter: getNodeType,
58
- nodePredicate: isNode,
59
- state: {
60
- sourceMap
61
- }
62
- });
63
- };
64
- var _default = exports.default = analyze;
@@ -1,59 +0,0 @@
1
- import { visit, getNodeType as getCSTNodeType, isNode as isCSTNode } from '@speclynx/apidom-ast';
2
- import { isElement, isParseResultElement, keyMap as keyMapApiDOM, getNodeType as getNodeTypeApiDOM } from '@speclynx/apidom-core';
3
- import CstVisitor from "./visitors/CstVisitor.mjs";
4
- import TreeCursorIterator from "../TreeCursorIterator.mjs";
5
- const keyMap = {
6
- document: ['children'],
7
- object: ['children'],
8
- array: ['children'],
9
- string: ['children'],
10
- property: ['children'],
11
- key: ['children'],
12
- error: ['children'],
13
- ...keyMapApiDOM
14
- };
15
- const getNodeType = node => {
16
- if (isParseResultElement(node)) {
17
- return 'ParseResultElement';
18
- }
19
- if (isElement(node)) {
20
- return getNodeTypeApiDOM(node);
21
- }
22
- return getCSTNodeType(node);
23
- };
24
-
25
- // @ts-ignore
26
- const isNode = element => isElement(element) || isCSTNode(element);
27
-
28
- /**
29
- * This version of syntactic analysis translates TreeSitter CTS
30
- * directly into ApiDOM.
31
- *
32
- * Transient transformation of TreeSitter CST is performed
33
- * using TreeSitter cursor. TreeSitter cursor is a stateful object
34
- * that allows us to walk syntax tree containing large number of nodes
35
- * with maximum efficiency. Using this transient CST transformation
36
- * gives us double the performance when syntactically analyzing
37
- * CST into ApiDOM.
38
- *
39
- * Single traversal pass is needed to get from CST to ApiDOM.
40
- * @public
41
- */
42
- const analyze = (cst, {
43
- sourceMap = false
44
- } = {}) => {
45
- const visitor = new CstVisitor();
46
- const cursor = cst.walk();
47
- const iterator = new TreeCursorIterator(cursor);
48
- const [rootNode] = Array.from(iterator);
49
- return visit(rootNode, visitor, {
50
- // @ts-ignore
51
- keyMap,
52
- nodeTypeGetter: getNodeType,
53
- nodePredicate: isNode,
54
- state: {
55
- sourceMap
56
- }
57
- });
58
- };
59
- export default analyze;
@@ -1,163 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
- exports.__esModule = true;
5
- exports.default = void 0;
6
- var _apidomCore = require("@speclynx/apidom-core");
7
- var _TreeCursorSyntaxNode = _interopRequireDefault(require("../../TreeCursorSyntaxNode.cjs"));
8
- class CstVisitor {
9
- static toPosition(node) {
10
- const start = new _apidomCore.ArrayElement([node.startPosition.row, node.startPosition.column, node.startIndex]);
11
- const end = new _apidomCore.ArrayElement([node.endPosition.row, node.endPosition.column, node.endIndex]);
12
- start.classes.push('position');
13
- end.classes.push('position');
14
- return [start, end];
15
- }
16
- sourceMap = false;
17
- annotations;
18
- ParseResultElement = {
19
- leave: element => {
20
- // mark first-non Annotation element as result
21
- // @ts-ignore
22
- const elements = element.findElements(_apidomCore.isPrimitiveElement);
23
- if (elements.length > 0) {
24
- const resultElement = elements[0];
25
- resultElement.classes.push('result');
26
- }
27
-
28
- // provide annotations
29
- this.annotations.forEach(annotationElement => {
30
- element.push(annotationElement);
31
- });
32
- this.annotations = [];
33
- }
34
- };
35
- constructor() {
36
- this.annotations = [];
37
- }
38
- enter(node) {
39
- // missing anonymous literals from CST transformed into AnnotationElements.
40
- if (node instanceof _TreeCursorSyntaxNode.default && !node.isNamed && node.isMissing) {
41
- // collect annotations from missing literals
42
- const value = node.type || node.text;
43
- const message = `(Missing ${value})`;
44
- const element = new _apidomCore.AnnotationElement(message);
45
- element.classes.push('warning');
46
- this.maybeAddSourceMap(node, element);
47
- this.annotations.push(element);
48
- }
49
- return null; // remove everything unrecognized
50
- }
51
- document(node) {
52
- const element = new _apidomCore.ParseResultElement();
53
- // @ts-ignore
54
- element._content = node.children;
55
- this.maybeAddSourceMap(node, element);
56
- return element;
57
- }
58
- object(node) {
59
- const element = new _apidomCore.ObjectElement();
60
- // @ts-ignore
61
- element._content = node.children;
62
- this.maybeAddSourceMap(node, element);
63
- return element;
64
- }
65
- array(node) {
66
- const element = new _apidomCore.ArrayElement();
67
- // @ts-ignore
68
- element._content = node.children;
69
- this.maybeAddSourceMap(node, element);
70
- return element;
71
- }
72
- pair(node) {
73
- const element = new _apidomCore.MemberElement();
74
- // @ts-ignore
75
- element.content.key = node.keyNode;
76
- // @ts-ignore
77
- element.content.value = node.valueNode;
78
- this.maybeAddSourceMap(node, element);
79
-
80
- /**
81
- * Process possible errors here that may be present in pair node children as we're using direct field access.
82
- * There are usually 3 children here found: "key", ":", "value".
83
- */
84
- if (node.children.length > 3) {
85
- node.children.filter(child => child.type === 'ERROR').forEach(errorNode => {
86
- this.ERROR(errorNode, node, [], [node]);
87
- });
88
- }
89
- return element;
90
- }
91
- string(node) {
92
- let element;
93
- try {
94
- element = new _apidomCore.StringElement(JSON.parse(node.text));
95
- } catch (error) {
96
- element = new _apidomCore.StringElement(node.text);
97
- if (error instanceof Error) {
98
- element.setMetaProperty('jsonParse', {
99
- isError: true,
100
- errorType: error.name,
101
- errorMessage: error.message
102
- });
103
- }
104
- }
105
- this.maybeAddSourceMap(node, element);
106
- return element;
107
- }
108
- number(node) {
109
- const element = new _apidomCore.NumberElement(Number(node.text));
110
- this.maybeAddSourceMap(node, element);
111
- return element;
112
- }
113
- null(node) {
114
- const element = new _apidomCore.NullElement();
115
- this.maybeAddSourceMap(node, element);
116
- return element;
117
- }
118
- true(node) {
119
- const element = new _apidomCore.BooleanElement(true);
120
- this.maybeAddSourceMap(node, element);
121
- return element;
122
- }
123
- false(node) {
124
- const element = new _apidomCore.BooleanElement(false);
125
- this.maybeAddSourceMap(node, element);
126
- return element;
127
- }
128
- ERROR(node, key, parent, path) {
129
- // collect errors as annotations
130
- const isUnexpected = !node.hasError;
131
- const value = node.text;
132
- const message = isUnexpected ? `(Unexpected ${value})` : `(Error ${value})`;
133
- const element = new _apidomCore.AnnotationElement(message);
134
- element.classes.push('error');
135
- this.maybeAddSourceMap(node, element);
136
- if (path.length === 0) {
137
- // no document to visit, only error is present in CST
138
- const parseResultElement = new _apidomCore.ParseResultElement();
139
- parseResultElement.push(element);
140
- return parseResultElement;
141
- }
142
-
143
- // we have CST node for document
144
- this.annotations.push(element);
145
- return null;
146
- }
147
- maybeAddSourceMap(node, element) {
148
- if (!this.sourceMap) {
149
- return;
150
- }
151
- const sourceMap = new _apidomCore.SourceMapElement();
152
- const position = CstVisitor.toPosition(node);
153
- if (position !== null) {
154
- const [start, end] = position;
155
- sourceMap.push(start);
156
- sourceMap.push(end);
157
- }
158
- // @ts-ignore
159
- sourceMap.astNode = node;
160
- element.meta.set('sourceMap', sourceMap);
161
- }
162
- }
163
- var _default = exports.default = CstVisitor;
@@ -1,158 +0,0 @@
1
- import { BooleanElement, NullElement, NumberElement, ParseResultElement, SourceMapElement, MemberElement, ObjectElement, ArrayElement, StringElement, AnnotationElement, isPrimitiveElement } from '@speclynx/apidom-core';
2
- import TreeCursorSyntaxNode from "../../TreeCursorSyntaxNode.mjs";
3
- class CstVisitor {
4
- static toPosition(node) {
5
- const start = new ArrayElement([node.startPosition.row, node.startPosition.column, node.startIndex]);
6
- const end = new ArrayElement([node.endPosition.row, node.endPosition.column, node.endIndex]);
7
- start.classes.push('position');
8
- end.classes.push('position');
9
- return [start, end];
10
- }
11
- sourceMap = false;
12
- annotations;
13
- ParseResultElement = {
14
- leave: element => {
15
- // mark first-non Annotation element as result
16
- // @ts-ignore
17
- const elements = element.findElements(isPrimitiveElement);
18
- if (elements.length > 0) {
19
- const resultElement = elements[0];
20
- resultElement.classes.push('result');
21
- }
22
-
23
- // provide annotations
24
- this.annotations.forEach(annotationElement => {
25
- element.push(annotationElement);
26
- });
27
- this.annotations = [];
28
- }
29
- };
30
- constructor() {
31
- this.annotations = [];
32
- }
33
- enter(node) {
34
- // missing anonymous literals from CST transformed into AnnotationElements.
35
- if (node instanceof TreeCursorSyntaxNode && !node.isNamed && node.isMissing) {
36
- // collect annotations from missing literals
37
- const value = node.type || node.text;
38
- const message = `(Missing ${value})`;
39
- const element = new AnnotationElement(message);
40
- element.classes.push('warning');
41
- this.maybeAddSourceMap(node, element);
42
- this.annotations.push(element);
43
- }
44
- return null; // remove everything unrecognized
45
- }
46
- document(node) {
47
- const element = new ParseResultElement();
48
- // @ts-ignore
49
- element._content = node.children;
50
- this.maybeAddSourceMap(node, element);
51
- return element;
52
- }
53
- object(node) {
54
- const element = new ObjectElement();
55
- // @ts-ignore
56
- element._content = node.children;
57
- this.maybeAddSourceMap(node, element);
58
- return element;
59
- }
60
- array(node) {
61
- const element = new ArrayElement();
62
- // @ts-ignore
63
- element._content = node.children;
64
- this.maybeAddSourceMap(node, element);
65
- return element;
66
- }
67
- pair(node) {
68
- const element = new MemberElement();
69
- // @ts-ignore
70
- element.content.key = node.keyNode;
71
- // @ts-ignore
72
- element.content.value = node.valueNode;
73
- this.maybeAddSourceMap(node, element);
74
-
75
- /**
76
- * Process possible errors here that may be present in pair node children as we're using direct field access.
77
- * There are usually 3 children here found: "key", ":", "value".
78
- */
79
- if (node.children.length > 3) {
80
- node.children.filter(child => child.type === 'ERROR').forEach(errorNode => {
81
- this.ERROR(errorNode, node, [], [node]);
82
- });
83
- }
84
- return element;
85
- }
86
- string(node) {
87
- let element;
88
- try {
89
- element = new StringElement(JSON.parse(node.text));
90
- } catch (error) {
91
- element = new StringElement(node.text);
92
- if (error instanceof Error) {
93
- element.setMetaProperty('jsonParse', {
94
- isError: true,
95
- errorType: error.name,
96
- errorMessage: error.message
97
- });
98
- }
99
- }
100
- this.maybeAddSourceMap(node, element);
101
- return element;
102
- }
103
- number(node) {
104
- const element = new NumberElement(Number(node.text));
105
- this.maybeAddSourceMap(node, element);
106
- return element;
107
- }
108
- null(node) {
109
- const element = new NullElement();
110
- this.maybeAddSourceMap(node, element);
111
- return element;
112
- }
113
- true(node) {
114
- const element = new BooleanElement(true);
115
- this.maybeAddSourceMap(node, element);
116
- return element;
117
- }
118
- false(node) {
119
- const element = new BooleanElement(false);
120
- this.maybeAddSourceMap(node, element);
121
- return element;
122
- }
123
- ERROR(node, key, parent, path) {
124
- // collect errors as annotations
125
- const isUnexpected = !node.hasError;
126
- const value = node.text;
127
- const message = isUnexpected ? `(Unexpected ${value})` : `(Error ${value})`;
128
- const element = new AnnotationElement(message);
129
- element.classes.push('error');
130
- this.maybeAddSourceMap(node, element);
131
- if (path.length === 0) {
132
- // no document to visit, only error is present in CST
133
- const parseResultElement = new ParseResultElement();
134
- parseResultElement.push(element);
135
- return parseResultElement;
136
- }
137
-
138
- // we have CST node for document
139
- this.annotations.push(element);
140
- return null;
141
- }
142
- maybeAddSourceMap(node, element) {
143
- if (!this.sourceMap) {
144
- return;
145
- }
146
- const sourceMap = new SourceMapElement();
147
- const position = CstVisitor.toPosition(node);
148
- if (position !== null) {
149
- const [start, end] = position;
150
- sourceMap.push(start);
151
- sourceMap.push(end);
152
- }
153
- // @ts-ignore
154
- sourceMap.astNode = node;
155
- element.meta.set('sourceMap', sourceMap);
156
- }
157
- }
158
- export default CstVisitor;
@@ -1,56 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
- var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
5
- exports.__esModule = true;
6
- exports.default = void 0;
7
- var _apidomAst = require("@speclynx/apidom-ast");
8
- var _TreeCursorIterator = _interopRequireDefault(require("../TreeCursorIterator.cjs"));
9
- var _CstVisitor = _interopRequireWildcard(require("./visitors/CstVisitor.cjs"));
10
- var _JsonAstVisitor = _interopRequireWildcard(require("./visitors/JsonAstVisitor.cjs"));
11
- /**
12
- * @public
13
- */
14
-
15
- /**
16
- * This version of syntactic analysis does following transformations:
17
- * `TreeSitter CST -> JSON AST -> ApiDOM`
18
- *
19
- * Transient transformation of TreeSitter CST is performed
20
- * using TreeSitter cursor. TreeSitter cursor is a stateful object
21
- * that allows us to walk syntax tree containing large number of nodes
22
- * with maximum efficiency. Using this transient CST transformation
23
- * gives us double the performance when syntactically analyzing
24
- * CST into JSON AST.
25
- *
26
- * Two traversals passes are needed to get from CST to ApiDOM.
27
- * This analysis is much slower than the direct one, but allows
28
- * to do additional analysis magic on JSON AST.
29
- * @public
30
- */
31
- const analyze = (cst, {
32
- sourceMap = false
33
- } = {}) => {
34
- const cursor = cst.walk();
35
- const iterator = new _TreeCursorIterator.default(cursor);
36
- const [rootNode] = Array.from(iterator);
37
- const cstVisitor = new _CstVisitor.default();
38
- const astVisitor = new _JsonAstVisitor.default();
39
- const jsonAst = (0, _apidomAst.visit)(rootNode, cstVisitor, {
40
- // @ts-ignore
41
- keyMap: _CstVisitor.keyMap,
42
- state: {
43
- sourceMap
44
- }
45
- });
46
- return (0, _apidomAst.visit)(jsonAst.rootNode, astVisitor, {
47
- // @ts-ignore
48
- keyMap: _JsonAstVisitor.keyMap,
49
- nodeTypeGetter: _JsonAstVisitor.getNodeType,
50
- nodePredicate: _JsonAstVisitor.isNode,
51
- state: {
52
- sourceMap
53
- }
54
- });
55
- };
56
- var _default = exports.default = analyze;
@@ -1,49 +0,0 @@
1
- import { visit } from '@speclynx/apidom-ast';
2
- import TreeCursorIterator from "../TreeCursorIterator.mjs";
3
- import CstVisitor, { keyMap as cstKeyMap } from "./visitors/CstVisitor.mjs";
4
- import JsonAstVisitor, { keyMap as astKeyMap, isNode, getNodeType } from "./visitors/JsonAstVisitor.mjs";
5
- /**
6
- * @public
7
- */
8
- /**
9
- * This version of syntactic analysis does following transformations:
10
- * `TreeSitter CST -> JSON AST -> ApiDOM`
11
- *
12
- * Transient transformation of TreeSitter CST is performed
13
- * using TreeSitter cursor. TreeSitter cursor is a stateful object
14
- * that allows us to walk syntax tree containing large number of nodes
15
- * with maximum efficiency. Using this transient CST transformation
16
- * gives us double the performance when syntactically analyzing
17
- * CST into JSON AST.
18
- *
19
- * Two traversals passes are needed to get from CST to ApiDOM.
20
- * This analysis is much slower than the direct one, but allows
21
- * to do additional analysis magic on JSON AST.
22
- * @public
23
- */
24
- const analyze = (cst, {
25
- sourceMap = false
26
- } = {}) => {
27
- const cursor = cst.walk();
28
- const iterator = new TreeCursorIterator(cursor);
29
- const [rootNode] = Array.from(iterator);
30
- const cstVisitor = new CstVisitor();
31
- const astVisitor = new JsonAstVisitor();
32
- const jsonAst = visit(rootNode, cstVisitor, {
33
- // @ts-ignore
34
- keyMap: cstKeyMap,
35
- state: {
36
- sourceMap
37
- }
38
- });
39
- return visit(jsonAst.rootNode, astVisitor, {
40
- // @ts-ignore
41
- keyMap: astKeyMap,
42
- nodeTypeGetter: getNodeType,
43
- nodePredicate: isNode,
44
- state: {
45
- sourceMap
46
- }
47
- });
48
- };
49
- export default analyze;