@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speclynx/apidom-parser-adapter-json",
3
- "version": "2.11.0",
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.11.0",
46
- "@speclynx/apidom-datamodel": "^2.11.0",
47
- "@speclynx/apidom-error": "^2.11.0",
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": "ee7e9488621be61f5dc1b098b8af135dc83c9ac1"
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 }