@speclynx/apidom-parser-adapter-json 2.11.0 → 2.12.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 +6 -0
- package/README.md +8 -2
- package/dist/apidom-parser-adapter-json.browser.js +174 -10
- package/dist/apidom-parser-adapter-json.browser.min.js +1 -1
- package/package.json +5 -5
- package/src/adapter.cjs +6 -1
- package/src/adapter.mjs +6 -1
- package/src/tree-sitter/index.cjs +4 -2
- package/src/tree-sitter/index.mjs +4 -2
- package/src/tree-sitter/syntactic-analysis/index.cjs +58 -1
- package/src/tree-sitter/syntactic-analysis/index.mjs +58 -1
- package/types/apidom-parser-adapter-json.d.ts +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speclynx/apidom-parser-adapter-json",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "Parser adapter for parsing JSON documents into base namespace.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"license": "Apache-2.0",
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@babel/runtime-corejs3": "^7.28.4",
|
|
45
|
-
"@speclynx/apidom-core": "^2.
|
|
46
|
-
"@speclynx/apidom-datamodel": "^2.
|
|
47
|
-
"@speclynx/apidom-error": "^2.
|
|
45
|
+
"@speclynx/apidom-core": "^2.12.0",
|
|
46
|
+
"@speclynx/apidom-datamodel": "^2.12.0",
|
|
47
|
+
"@speclynx/apidom-error": "^2.12.0",
|
|
48
48
|
"web-tree-sitter": "=0.26.5"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"README.md",
|
|
62
62
|
"CHANGELOG.md"
|
|
63
63
|
],
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "672efe907afef6ae5b547a8028db077297a0c52e"
|
|
65
65
|
}
|
package/src/adapter.cjs
CHANGED
|
@@ -51,16 +51,21 @@ exports.detect = detect;
|
|
|
51
51
|
*/
|
|
52
52
|
const parse = async (source, {
|
|
53
53
|
sourceMap = false,
|
|
54
|
+
style = false,
|
|
54
55
|
strict = false
|
|
55
56
|
} = {}) => {
|
|
56
57
|
if (strict && sourceMap) {
|
|
57
58
|
throw new _apidomError.UnsupportedOperationError('Cannot use sourceMap with strict parsing. Strict parsing does not support source maps.');
|
|
58
59
|
}
|
|
60
|
+
if (strict && style) {
|
|
61
|
+
throw new _apidomError.UnsupportedOperationError('Cannot use style with strict parsing. Strict parsing does not support style preservation.');
|
|
62
|
+
}
|
|
59
63
|
if (strict) {
|
|
60
64
|
return native.parse(source);
|
|
61
65
|
}
|
|
62
66
|
return treeSitter.parse(source, {
|
|
63
|
-
sourceMap
|
|
67
|
+
sourceMap,
|
|
68
|
+
style
|
|
64
69
|
});
|
|
65
70
|
};
|
|
66
71
|
exports.parse = parse;
|
package/src/adapter.mjs
CHANGED
|
@@ -42,15 +42,20 @@ export const detect = async (source, {
|
|
|
42
42
|
*/
|
|
43
43
|
export const parse = async (source, {
|
|
44
44
|
sourceMap = false,
|
|
45
|
+
style = false,
|
|
45
46
|
strict = false
|
|
46
47
|
} = {}) => {
|
|
47
48
|
if (strict && sourceMap) {
|
|
48
49
|
throw new UnsupportedOperationError('Cannot use sourceMap with strict parsing. Strict parsing does not support source maps.');
|
|
49
50
|
}
|
|
51
|
+
if (strict && style) {
|
|
52
|
+
throw new UnsupportedOperationError('Cannot use style with strict parsing. Strict parsing does not support style preservation.');
|
|
53
|
+
}
|
|
50
54
|
if (strict) {
|
|
51
55
|
return native.parse(source);
|
|
52
56
|
}
|
|
53
57
|
return treeSitter.parse(source, {
|
|
54
|
-
sourceMap
|
|
58
|
+
sourceMap,
|
|
59
|
+
style
|
|
55
60
|
});
|
|
56
61
|
};
|
|
@@ -40,12 +40,14 @@ exports.detect = detect;
|
|
|
40
40
|
* @public
|
|
41
41
|
*/
|
|
42
42
|
const parse = async (source, {
|
|
43
|
-
sourceMap = false
|
|
43
|
+
sourceMap = false,
|
|
44
|
+
style = false
|
|
44
45
|
} = {}) => {
|
|
45
46
|
const cst = await (0, _index.default)(source);
|
|
46
47
|
try {
|
|
47
48
|
return (0, _index2.default)(cst, {
|
|
48
|
-
sourceMap
|
|
49
|
+
sourceMap,
|
|
50
|
+
style
|
|
49
51
|
});
|
|
50
52
|
} finally {
|
|
51
53
|
cst.delete();
|
|
@@ -35,12 +35,14 @@ export const detect = async source => {
|
|
|
35
35
|
* @public
|
|
36
36
|
*/
|
|
37
37
|
export const parse = async (source, {
|
|
38
|
-
sourceMap = false
|
|
38
|
+
sourceMap = false,
|
|
39
|
+
style = false
|
|
39
40
|
} = {}) => {
|
|
40
41
|
const cst = await lexicalAnalysis(source);
|
|
41
42
|
try {
|
|
42
43
|
return syntacticAnalysis(cst, {
|
|
43
|
-
sourceMap
|
|
44
|
+
sourceMap,
|
|
45
|
+
style
|
|
44
46
|
});
|
|
45
47
|
} finally {
|
|
46
48
|
cst.delete();
|
|
@@ -26,6 +26,24 @@ const maybeAddSourceMap = (info, element, ctx) => {
|
|
|
26
26
|
element.endCharacter = info.endPosition.column;
|
|
27
27
|
element.endOffset = info.endIndex;
|
|
28
28
|
};
|
|
29
|
+
|
|
30
|
+
// build json style object for an element
|
|
31
|
+
const buildJsonStyle = (ctx, extras) => {
|
|
32
|
+
const jsonStyle = {
|
|
33
|
+
indent: ctx.indent
|
|
34
|
+
};
|
|
35
|
+
if (extras) Object.assign(jsonStyle, extras);
|
|
36
|
+
return {
|
|
37
|
+
json: jsonStyle
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// detect indent from an object's first pair child position
|
|
42
|
+
// called during transformChildren when we encounter the first pair
|
|
43
|
+
const detectIndent = (objectColumn, firstPairColumn) => {
|
|
44
|
+
const diff = firstPairColumn - objectColumn;
|
|
45
|
+
return diff > 0 ? diff : 2;
|
|
46
|
+
};
|
|
29
47
|
const transform = (cursor, transformerMap, ctx) => {
|
|
30
48
|
const info = getCursorInfo(cursor);
|
|
31
49
|
|
|
@@ -89,11 +107,27 @@ const createTransformers = transformerMap => ({
|
|
|
89
107
|
const element = new _apidomDatamodel.ObjectElement();
|
|
90
108
|
maybeAddSourceMap(info, element, ctx);
|
|
91
109
|
|
|
110
|
+
// Detect indent from first pair if style is enabled and not yet detected
|
|
111
|
+
if (ctx.style && ctx.indent === 0) {
|
|
112
|
+
if (cursor.gotoFirstChild()) {
|
|
113
|
+
do {
|
|
114
|
+
if (cursor.nodeType === 'pair') {
|
|
115
|
+
ctx.indent = detectIndent(info.startPosition.column, cursor.startPosition.column);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
} while (cursor.gotoNextSibling());
|
|
119
|
+
cursor.gotoParent();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
92
123
|
// Transform children (pairs)
|
|
93
124
|
const children = transformChildren(cursor, transformerMap, ctx);
|
|
94
125
|
for (const child of children) {
|
|
95
126
|
element.push(child);
|
|
96
127
|
}
|
|
128
|
+
if (ctx.style) {
|
|
129
|
+
element.style = buildJsonStyle(ctx);
|
|
130
|
+
}
|
|
97
131
|
return element;
|
|
98
132
|
},
|
|
99
133
|
array(cursor, ctx) {
|
|
@@ -106,6 +140,9 @@ const createTransformers = transformerMap => ({
|
|
|
106
140
|
for (const child of children) {
|
|
107
141
|
element.push(child);
|
|
108
142
|
}
|
|
143
|
+
if (ctx.style) {
|
|
144
|
+
element.style = buildJsonStyle(ctx);
|
|
145
|
+
}
|
|
109
146
|
return element;
|
|
110
147
|
},
|
|
111
148
|
pair(cursor, ctx) {
|
|
@@ -147,30 +184,47 @@ const createTransformers = transformerMap => ({
|
|
|
147
184
|
});
|
|
148
185
|
}
|
|
149
186
|
}
|
|
187
|
+
if (ctx.style) {
|
|
188
|
+
element.style = buildJsonStyle(ctx);
|
|
189
|
+
}
|
|
150
190
|
maybeAddSourceMap(info, element, ctx);
|
|
151
191
|
return element;
|
|
152
192
|
},
|
|
153
193
|
number(cursor, ctx) {
|
|
154
194
|
const info = getCursorInfo(cursor);
|
|
155
195
|
const element = new _apidomDatamodel.NumberElement(Number(info.text));
|
|
196
|
+
if (ctx.style) {
|
|
197
|
+
element.style = buildJsonStyle(ctx, {
|
|
198
|
+
rawContent: info.text
|
|
199
|
+
});
|
|
200
|
+
}
|
|
156
201
|
maybeAddSourceMap(info, element, ctx);
|
|
157
202
|
return element;
|
|
158
203
|
},
|
|
159
204
|
null(cursor, ctx) {
|
|
160
205
|
const info = getCursorInfo(cursor);
|
|
161
206
|
const element = new _apidomDatamodel.NullElement();
|
|
207
|
+
if (ctx.style) {
|
|
208
|
+
element.style = buildJsonStyle(ctx);
|
|
209
|
+
}
|
|
162
210
|
maybeAddSourceMap(info, element, ctx);
|
|
163
211
|
return element;
|
|
164
212
|
},
|
|
165
213
|
true(cursor, ctx) {
|
|
166
214
|
const info = getCursorInfo(cursor);
|
|
167
215
|
const element = new _apidomDatamodel.BooleanElement(true);
|
|
216
|
+
if (ctx.style) {
|
|
217
|
+
element.style = buildJsonStyle(ctx);
|
|
218
|
+
}
|
|
168
219
|
maybeAddSourceMap(info, element, ctx);
|
|
169
220
|
return element;
|
|
170
221
|
},
|
|
171
222
|
false(cursor, ctx) {
|
|
172
223
|
const info = getCursorInfo(cursor);
|
|
173
224
|
const element = new _apidomDatamodel.BooleanElement(false);
|
|
225
|
+
if (ctx.style) {
|
|
226
|
+
element.style = buildJsonStyle(ctx);
|
|
227
|
+
}
|
|
174
228
|
maybeAddSourceMap(info, element, ctx);
|
|
175
229
|
return element;
|
|
176
230
|
},
|
|
@@ -201,11 +255,14 @@ Object.assign(transformers, createTransformers(transformers));
|
|
|
201
255
|
* @public
|
|
202
256
|
*/
|
|
203
257
|
const analyze = (cst, {
|
|
204
|
-
sourceMap = false
|
|
258
|
+
sourceMap = false,
|
|
259
|
+
style = false
|
|
205
260
|
} = {}) => {
|
|
206
261
|
const cursor = cst.walk();
|
|
207
262
|
const ctx = {
|
|
208
263
|
sourceMap,
|
|
264
|
+
style,
|
|
265
|
+
indent: 0,
|
|
209
266
|
annotations: []
|
|
210
267
|
};
|
|
211
268
|
const result = transform(cursor, transformers, ctx);
|
|
@@ -22,6 +22,24 @@ const maybeAddSourceMap = (info, element, ctx) => {
|
|
|
22
22
|
element.endCharacter = info.endPosition.column;
|
|
23
23
|
element.endOffset = info.endIndex;
|
|
24
24
|
};
|
|
25
|
+
|
|
26
|
+
// build json style object for an element
|
|
27
|
+
const buildJsonStyle = (ctx, extras) => {
|
|
28
|
+
const jsonStyle = {
|
|
29
|
+
indent: ctx.indent
|
|
30
|
+
};
|
|
31
|
+
if (extras) Object.assign(jsonStyle, extras);
|
|
32
|
+
return {
|
|
33
|
+
json: jsonStyle
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// detect indent from an object's first pair child position
|
|
38
|
+
// called during transformChildren when we encounter the first pair
|
|
39
|
+
const detectIndent = (objectColumn, firstPairColumn) => {
|
|
40
|
+
const diff = firstPairColumn - objectColumn;
|
|
41
|
+
return diff > 0 ? diff : 2;
|
|
42
|
+
};
|
|
25
43
|
const transform = (cursor, transformerMap, ctx) => {
|
|
26
44
|
const info = getCursorInfo(cursor);
|
|
27
45
|
|
|
@@ -85,11 +103,27 @@ const createTransformers = transformerMap => ({
|
|
|
85
103
|
const element = new ObjectElement();
|
|
86
104
|
maybeAddSourceMap(info, element, ctx);
|
|
87
105
|
|
|
106
|
+
// Detect indent from first pair if style is enabled and not yet detected
|
|
107
|
+
if (ctx.style && ctx.indent === 0) {
|
|
108
|
+
if (cursor.gotoFirstChild()) {
|
|
109
|
+
do {
|
|
110
|
+
if (cursor.nodeType === 'pair') {
|
|
111
|
+
ctx.indent = detectIndent(info.startPosition.column, cursor.startPosition.column);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
} while (cursor.gotoNextSibling());
|
|
115
|
+
cursor.gotoParent();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
88
119
|
// Transform children (pairs)
|
|
89
120
|
const children = transformChildren(cursor, transformerMap, ctx);
|
|
90
121
|
for (const child of children) {
|
|
91
122
|
element.push(child);
|
|
92
123
|
}
|
|
124
|
+
if (ctx.style) {
|
|
125
|
+
element.style = buildJsonStyle(ctx);
|
|
126
|
+
}
|
|
93
127
|
return element;
|
|
94
128
|
},
|
|
95
129
|
array(cursor, ctx) {
|
|
@@ -102,6 +136,9 @@ const createTransformers = transformerMap => ({
|
|
|
102
136
|
for (const child of children) {
|
|
103
137
|
element.push(child);
|
|
104
138
|
}
|
|
139
|
+
if (ctx.style) {
|
|
140
|
+
element.style = buildJsonStyle(ctx);
|
|
141
|
+
}
|
|
105
142
|
return element;
|
|
106
143
|
},
|
|
107
144
|
pair(cursor, ctx) {
|
|
@@ -143,30 +180,47 @@ const createTransformers = transformerMap => ({
|
|
|
143
180
|
});
|
|
144
181
|
}
|
|
145
182
|
}
|
|
183
|
+
if (ctx.style) {
|
|
184
|
+
element.style = buildJsonStyle(ctx);
|
|
185
|
+
}
|
|
146
186
|
maybeAddSourceMap(info, element, ctx);
|
|
147
187
|
return element;
|
|
148
188
|
},
|
|
149
189
|
number(cursor, ctx) {
|
|
150
190
|
const info = getCursorInfo(cursor);
|
|
151
191
|
const element = new NumberElement(Number(info.text));
|
|
192
|
+
if (ctx.style) {
|
|
193
|
+
element.style = buildJsonStyle(ctx, {
|
|
194
|
+
rawContent: info.text
|
|
195
|
+
});
|
|
196
|
+
}
|
|
152
197
|
maybeAddSourceMap(info, element, ctx);
|
|
153
198
|
return element;
|
|
154
199
|
},
|
|
155
200
|
null(cursor, ctx) {
|
|
156
201
|
const info = getCursorInfo(cursor);
|
|
157
202
|
const element = new NullElement();
|
|
203
|
+
if (ctx.style) {
|
|
204
|
+
element.style = buildJsonStyle(ctx);
|
|
205
|
+
}
|
|
158
206
|
maybeAddSourceMap(info, element, ctx);
|
|
159
207
|
return element;
|
|
160
208
|
},
|
|
161
209
|
true(cursor, ctx) {
|
|
162
210
|
const info = getCursorInfo(cursor);
|
|
163
211
|
const element = new BooleanElement(true);
|
|
212
|
+
if (ctx.style) {
|
|
213
|
+
element.style = buildJsonStyle(ctx);
|
|
214
|
+
}
|
|
164
215
|
maybeAddSourceMap(info, element, ctx);
|
|
165
216
|
return element;
|
|
166
217
|
},
|
|
167
218
|
false(cursor, ctx) {
|
|
168
219
|
const info = getCursorInfo(cursor);
|
|
169
220
|
const element = new BooleanElement(false);
|
|
221
|
+
if (ctx.style) {
|
|
222
|
+
element.style = buildJsonStyle(ctx);
|
|
223
|
+
}
|
|
170
224
|
maybeAddSourceMap(info, element, ctx);
|
|
171
225
|
return element;
|
|
172
226
|
},
|
|
@@ -197,11 +251,14 @@ Object.assign(transformers, createTransformers(transformers));
|
|
|
197
251
|
* @public
|
|
198
252
|
*/
|
|
199
253
|
const analyze = (cst, {
|
|
200
|
-
sourceMap = false
|
|
254
|
+
sourceMap = false,
|
|
255
|
+
style = false
|
|
201
256
|
} = {}) => {
|
|
202
257
|
const cursor = cst.walk();
|
|
203
258
|
const ctx = {
|
|
204
259
|
sourceMap,
|
|
260
|
+
style,
|
|
261
|
+
indent: 0,
|
|
205
262
|
annotations: []
|
|
206
263
|
};
|
|
207
264
|
const result = transform(cursor, transformers, ctx);
|
|
@@ -43,7 +43,7 @@ export declare const namespace: Namespace;
|
|
|
43
43
|
/**
|
|
44
44
|
* @public
|
|
45
45
|
*/
|
|
46
|
-
export declare const parse: (source: string, { sourceMap, strict }?: ParseOptions) => Promise<ParseResultElement>;
|
|
46
|
+
export declare const parse: (source: string, { sourceMap, style, strict }?: ParseOptions) => Promise<ParseResultElement>;
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* @public
|
|
@@ -57,6 +57,7 @@ export declare interface ParseDetectOptions {
|
|
|
57
57
|
*/
|
|
58
58
|
export declare interface ParseOptions {
|
|
59
59
|
sourceMap?: boolean;
|
|
60
|
+
style?: boolean;
|
|
60
61
|
strict?: boolean;
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -70,8 +71,9 @@ export declare interface ParseOptions {
|
|
|
70
71
|
* Single pass transformation from CST to ApiDOM.
|
|
71
72
|
* @public
|
|
72
73
|
*/
|
|
73
|
-
export declare const syntacticAnalysis: (cst: Tree, { sourceMap }?: {
|
|
74
|
+
export declare const syntacticAnalysis: (cst: Tree, { sourceMap, style }?: {
|
|
74
75
|
sourceMap?: boolean | undefined;
|
|
76
|
+
style?: boolean | undefined;
|
|
75
77
|
}) => ParseResultElement;
|
|
76
78
|
|
|
77
79
|
export { Tree }
|