@openrewrite/rewrite 8.69.0-20251212-132620 → 8.69.0-20251212-152027
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/dist/javascript/index.d.ts +1 -0
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +1 -0
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/tree-debug.d.ts +140 -0
- package/dist/javascript/tree-debug.d.ts.map +1 -0
- package/dist/javascript/tree-debug.js +892 -0
- package/dist/javascript/tree-debug.js.map +1 -0
- package/dist/version.txt +1 -1
- package/package.json +1 -1
- package/src/javascript/index.ts +1 -0
- package/src/javascript/tree-debug.ts +937 -0
|
@@ -0,0 +1,892 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2025 the original author or authors.
|
|
4
|
+
* <p>
|
|
5
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
* <p>
|
|
9
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
10
|
+
* <p>
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
51
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
52
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
53
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
54
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
55
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
56
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
|
+
exports.LstDebugVisitor = exports.LstDebugPrinter = void 0;
|
|
61
|
+
exports.formatWhitespace = formatWhitespace;
|
|
62
|
+
exports.formatSpace = formatSpace;
|
|
63
|
+
exports.formatCursorMessages = formatCursorMessages;
|
|
64
|
+
exports.findPropertyPath = findPropertyPath;
|
|
65
|
+
exports.debugPrint = debugPrint;
|
|
66
|
+
exports.debugPrintCursorPath = debugPrintCursorPath;
|
|
67
|
+
const java_1 = require("../java");
|
|
68
|
+
const visitor_1 = require("./visitor");
|
|
69
|
+
const fs = __importStar(require("fs"));
|
|
70
|
+
const DEFAULT_OPTIONS = {
|
|
71
|
+
includeCursorMessages: true,
|
|
72
|
+
includeMarkers: false,
|
|
73
|
+
includeIds: false,
|
|
74
|
+
maxDepth: -1,
|
|
75
|
+
excludeProperties: [],
|
|
76
|
+
output: 'console',
|
|
77
|
+
indent: ' ',
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Properties to always exclude from debug output (noisy/large).
|
|
81
|
+
*/
|
|
82
|
+
const EXCLUDED_PROPERTIES = new Set([
|
|
83
|
+
'type', // JavaType - very verbose
|
|
84
|
+
'methodType', // JavaType.Method
|
|
85
|
+
'variableType', // JavaType.Variable
|
|
86
|
+
'fieldType', // JavaType.Variable
|
|
87
|
+
'constructorType', // JavaType.Method
|
|
88
|
+
]);
|
|
89
|
+
/**
|
|
90
|
+
* Subscript digits for counts (index 0-9 maps to ₀-₉).
|
|
91
|
+
*/
|
|
92
|
+
const SUBSCRIPTS = ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉'];
|
|
93
|
+
/**
|
|
94
|
+
* Format a count as subscript. Count of 1 is implicit (empty string).
|
|
95
|
+
*/
|
|
96
|
+
function subscript(count) {
|
|
97
|
+
if (count <= 1)
|
|
98
|
+
return '';
|
|
99
|
+
if (count < 10)
|
|
100
|
+
return SUBSCRIPTS[count];
|
|
101
|
+
// For counts >= 10, build from individual digits
|
|
102
|
+
return String(count).split('').map(d => SUBSCRIPTS[parseInt(d)]).join('');
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Format whitespace string for readable debug output.
|
|
106
|
+
* Uses compact notation with subscript counts:
|
|
107
|
+
* - '\n' = 1 newline (implicit ₁)
|
|
108
|
+
* - '\n₂' = 2 newlines
|
|
109
|
+
* - '·₄' = 4 spaces
|
|
110
|
+
* - '-₂' = 2 tabs
|
|
111
|
+
* - '\n·₄' = newline + 4 spaces
|
|
112
|
+
* - '\n·₄-₂' = newline + 4 spaces + 2 tabs
|
|
113
|
+
*/
|
|
114
|
+
function formatWhitespace(whitespace) {
|
|
115
|
+
if (whitespace === undefined || whitespace === '') {
|
|
116
|
+
return "''";
|
|
117
|
+
}
|
|
118
|
+
let result = '';
|
|
119
|
+
let newlineCount = 0;
|
|
120
|
+
let spaceCount = 0;
|
|
121
|
+
let tabCount = 0;
|
|
122
|
+
const flushCounts = () => {
|
|
123
|
+
if (newlineCount > 0) {
|
|
124
|
+
result += '\\n' + subscript(newlineCount);
|
|
125
|
+
newlineCount = 0;
|
|
126
|
+
}
|
|
127
|
+
if (spaceCount > 0) {
|
|
128
|
+
result += '·' + subscript(spaceCount);
|
|
129
|
+
spaceCount = 0;
|
|
130
|
+
}
|
|
131
|
+
if (tabCount > 0) {
|
|
132
|
+
result += '-' + subscript(tabCount);
|
|
133
|
+
tabCount = 0;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
for (let i = 0; i < whitespace.length; i++) {
|
|
137
|
+
const c = whitespace[i];
|
|
138
|
+
if (c === '\n') {
|
|
139
|
+
// Flush spaces/tabs before starting newline count
|
|
140
|
+
if (spaceCount > 0 || tabCount > 0) {
|
|
141
|
+
flushCounts();
|
|
142
|
+
}
|
|
143
|
+
newlineCount++;
|
|
144
|
+
}
|
|
145
|
+
else if (c === '\r') {
|
|
146
|
+
flushCounts();
|
|
147
|
+
result += '\\r';
|
|
148
|
+
}
|
|
149
|
+
else if (c === ' ') {
|
|
150
|
+
// Flush newlines and tabs before counting spaces
|
|
151
|
+
if (newlineCount > 0) {
|
|
152
|
+
result += '\\n' + subscript(newlineCount);
|
|
153
|
+
newlineCount = 0;
|
|
154
|
+
}
|
|
155
|
+
if (tabCount > 0) {
|
|
156
|
+
result += '-' + subscript(tabCount);
|
|
157
|
+
tabCount = 0;
|
|
158
|
+
}
|
|
159
|
+
spaceCount++;
|
|
160
|
+
}
|
|
161
|
+
else if (c === '\t') {
|
|
162
|
+
// Flush newlines and spaces before counting tabs
|
|
163
|
+
if (newlineCount > 0) {
|
|
164
|
+
result += '\\n' + subscript(newlineCount);
|
|
165
|
+
newlineCount = 0;
|
|
166
|
+
}
|
|
167
|
+
if (spaceCount > 0) {
|
|
168
|
+
result += '·' + subscript(spaceCount);
|
|
169
|
+
spaceCount = 0;
|
|
170
|
+
}
|
|
171
|
+
tabCount++;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
flushCounts();
|
|
175
|
+
// Unexpected character (probably a bug in the parser)
|
|
176
|
+
result += c;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
flushCounts();
|
|
180
|
+
return `'${result}'`;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Format a single comment for debug output.
|
|
184
|
+
*/
|
|
185
|
+
function formatComment(comment) {
|
|
186
|
+
var _a;
|
|
187
|
+
const textComment = comment;
|
|
188
|
+
const text = (_a = textComment.text) !== null && _a !== void 0 ? _a : '';
|
|
189
|
+
// Truncate long comments
|
|
190
|
+
const truncated = text.length > 20 ? text.substring(0, 17) + '...' : text;
|
|
191
|
+
if (textComment.multiline) {
|
|
192
|
+
return `/*${truncated}*/`;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
return `//${truncated}`;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Format a J.Space for debug output.
|
|
200
|
+
*
|
|
201
|
+
* Compact format:
|
|
202
|
+
* - Empty space: `''`
|
|
203
|
+
* - Whitespace only: `'\n·₄'`
|
|
204
|
+
* - Comment only: `//comment`
|
|
205
|
+
* - Comment with suffix: `//comment'\n'`
|
|
206
|
+
* - Multiple comments: `//c1'\n' + //c2'\n·₄'`
|
|
207
|
+
*/
|
|
208
|
+
function formatSpace(space) {
|
|
209
|
+
if (space === undefined) {
|
|
210
|
+
return '<undefined>';
|
|
211
|
+
}
|
|
212
|
+
const hasComments = space.comments.length > 0;
|
|
213
|
+
const hasWhitespace = space.whitespace !== undefined && space.whitespace !== '';
|
|
214
|
+
// Completely empty
|
|
215
|
+
if (!hasComments && !hasWhitespace) {
|
|
216
|
+
return "''";
|
|
217
|
+
}
|
|
218
|
+
// Whitespace only (common case) - just show the formatted whitespace
|
|
219
|
+
if (!hasComments) {
|
|
220
|
+
return formatWhitespace(space.whitespace);
|
|
221
|
+
}
|
|
222
|
+
// Format comments with their suffixes
|
|
223
|
+
const parts = [];
|
|
224
|
+
for (const comment of space.comments) {
|
|
225
|
+
let part = formatComment(comment);
|
|
226
|
+
// Add suffix if present
|
|
227
|
+
if (comment.suffix && comment.suffix !== '') {
|
|
228
|
+
part += formatWhitespace(comment.suffix);
|
|
229
|
+
}
|
|
230
|
+
parts.push(part);
|
|
231
|
+
}
|
|
232
|
+
// Add trailing whitespace if present
|
|
233
|
+
if (hasWhitespace) {
|
|
234
|
+
parts.push(formatWhitespace(space.whitespace));
|
|
235
|
+
}
|
|
236
|
+
return parts.join(' + ');
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Format cursor messages for debug output.
|
|
240
|
+
* Returns '<no messages>' if no messages, otherwise returns '⟨key=value, ...⟩'
|
|
241
|
+
*/
|
|
242
|
+
function formatCursorMessages(cursor) {
|
|
243
|
+
if (!cursor || cursor.messages.size === 0) {
|
|
244
|
+
return '<no messages>';
|
|
245
|
+
}
|
|
246
|
+
const entries = [];
|
|
247
|
+
cursor.messages.forEach((value, key) => {
|
|
248
|
+
let valueStr;
|
|
249
|
+
if (Array.isArray(value)) {
|
|
250
|
+
valueStr = `[${value.map(v => JSON.stringify(v)).join(', ')}]`;
|
|
251
|
+
}
|
|
252
|
+
else if (typeof value === 'object' && value !== null) {
|
|
253
|
+
valueStr = JSON.stringify(value);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
valueStr = String(value);
|
|
257
|
+
}
|
|
258
|
+
const keyStr = typeof key === 'symbol' ? key.toString() : String(key);
|
|
259
|
+
entries.push(`${keyStr}=${valueStr}`);
|
|
260
|
+
});
|
|
261
|
+
return `⟨${entries.join(', ')}⟩`;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Get a short type name from a kind string.
|
|
265
|
+
*/
|
|
266
|
+
function shortTypeName(kind) {
|
|
267
|
+
if (!kind)
|
|
268
|
+
return 'Unknown';
|
|
269
|
+
// Extract the last part after the last dot
|
|
270
|
+
const lastDot = kind.lastIndexOf('.');
|
|
271
|
+
return lastDot >= 0 ? kind.substring(lastDot + 1) : kind;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Find which property of the parent contains the given child element.
|
|
275
|
+
* Returns the property name, or property name with array index if in an array.
|
|
276
|
+
* Returns undefined if the relationship cannot be determined.
|
|
277
|
+
*
|
|
278
|
+
* @param cursor - The cursor at the current position
|
|
279
|
+
* @param child - Optional: the actual child node being visited (for RightPadded/LeftPadded/Container visits where cursor.value is the parent)
|
|
280
|
+
*/
|
|
281
|
+
function findPropertyPath(cursor, child) {
|
|
282
|
+
var _a, _b, _c, _d;
|
|
283
|
+
if (!cursor) {
|
|
284
|
+
return undefined;
|
|
285
|
+
}
|
|
286
|
+
// If child is provided, use cursor.value as parent; otherwise use cursor.parent.value
|
|
287
|
+
const actualChild = child !== null && child !== void 0 ? child : cursor.value;
|
|
288
|
+
const parent = child ? cursor.value : (_a = cursor.parent) === null || _a === void 0 ? void 0 : _a.value;
|
|
289
|
+
if (!parent || typeof parent !== 'object') {
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
// Properties to skip when searching
|
|
293
|
+
const skipProps = new Set(['kind', 'id', 'prefix', 'markers', 'type', 'methodType', 'variableType', 'fieldType', 'constructorType']);
|
|
294
|
+
// Special case: if parent is a Container, we need to look at grandparent to find the property name
|
|
295
|
+
if (parent.kind === java_1.J.Kind.Container) {
|
|
296
|
+
const container = parent;
|
|
297
|
+
const grandparent = child ? (_b = cursor.parent) === null || _b === void 0 ? void 0 : _b.value : (_d = (_c = cursor.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d.value;
|
|
298
|
+
// Find the index of actualChild in container.elements
|
|
299
|
+
let childIndex = -1;
|
|
300
|
+
if (container.elements) {
|
|
301
|
+
for (let i = 0; i < container.elements.length; i++) {
|
|
302
|
+
if (container.elements[i] === actualChild) {
|
|
303
|
+
childIndex = i;
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// Find which property of grandparent holds this container
|
|
309
|
+
if (grandparent && typeof grandparent === 'object') {
|
|
310
|
+
for (const [key, value] of Object.entries(grandparent)) {
|
|
311
|
+
if (skipProps.has(key))
|
|
312
|
+
continue;
|
|
313
|
+
if (value === parent) {
|
|
314
|
+
if (childIndex >= 0) {
|
|
315
|
+
return `${key}[${childIndex}]`;
|
|
316
|
+
}
|
|
317
|
+
return key;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// Fallback: just show the index
|
|
322
|
+
if (childIndex >= 0) {
|
|
323
|
+
return `[${childIndex}]`;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
for (const [key, value] of Object.entries(parent)) {
|
|
327
|
+
if (skipProps.has(key))
|
|
328
|
+
continue;
|
|
329
|
+
// Direct match
|
|
330
|
+
if (value === actualChild) {
|
|
331
|
+
return key;
|
|
332
|
+
}
|
|
333
|
+
// Check if child is in an array
|
|
334
|
+
if (Array.isArray(value)) {
|
|
335
|
+
for (let i = 0; i < value.length; i++) {
|
|
336
|
+
if (value[i] === actualChild) {
|
|
337
|
+
return `${key}[${i}]`;
|
|
338
|
+
}
|
|
339
|
+
// Check inside RightPadded/LeftPadded wrappers
|
|
340
|
+
if (value[i] && typeof value[i] === 'object') {
|
|
341
|
+
if (value[i].element === actualChild) {
|
|
342
|
+
return `${key}[${i}].element`;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Check inside Container
|
|
348
|
+
if (value && typeof value === 'object' && value.kind === java_1.J.Kind.Container) {
|
|
349
|
+
const container = value;
|
|
350
|
+
if (container.elements) {
|
|
351
|
+
for (let i = 0; i < container.elements.length; i++) {
|
|
352
|
+
const rp = container.elements[i];
|
|
353
|
+
if (rp === actualChild) {
|
|
354
|
+
return `${key}[${i}]`;
|
|
355
|
+
}
|
|
356
|
+
if (rp.element === actualChild) {
|
|
357
|
+
return `${key}[${i}].element`;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Check inside LeftPadded/RightPadded
|
|
363
|
+
if (value && typeof value === 'object') {
|
|
364
|
+
if (value.kind === java_1.J.Kind.LeftPadded || value.kind === java_1.J.Kind.RightPadded) {
|
|
365
|
+
if (value.element === actualChild) {
|
|
366
|
+
return `${key}.element`;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return undefined;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Format a literal value for inline display.
|
|
375
|
+
*/
|
|
376
|
+
function formatLiteralValue(lit) {
|
|
377
|
+
if (lit.valueSource !== undefined) {
|
|
378
|
+
// Truncate long literals
|
|
379
|
+
return lit.valueSource.length > 20
|
|
380
|
+
? lit.valueSource.substring(0, 17) + '...'
|
|
381
|
+
: lit.valueSource;
|
|
382
|
+
}
|
|
383
|
+
return String(lit.value);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Get a compact inline summary for certain node types.
|
|
387
|
+
* - For Identifier: shows "simpleName"
|
|
388
|
+
* - For Literal: shows the value
|
|
389
|
+
* - For other nodes: shows all Identifier/Literal properties inline
|
|
390
|
+
*/
|
|
391
|
+
function getNodeSummary(node) {
|
|
392
|
+
if ((0, java_1.isIdentifier)(node)) {
|
|
393
|
+
return `"${node.simpleName}"`;
|
|
394
|
+
}
|
|
395
|
+
if ((0, java_1.isLiteral)(node)) {
|
|
396
|
+
return formatLiteralValue(node);
|
|
397
|
+
}
|
|
398
|
+
// For other nodes, find all Identifier and Literal properties
|
|
399
|
+
const parts = [];
|
|
400
|
+
const skipProps = new Set(['kind', 'id', 'prefix', 'markers', 'type', 'methodType', 'variableType', 'fieldType', 'constructorType']);
|
|
401
|
+
for (const [key, value] of Object.entries(node)) {
|
|
402
|
+
if (skipProps.has(key))
|
|
403
|
+
continue;
|
|
404
|
+
if (value === null || value === undefined)
|
|
405
|
+
continue;
|
|
406
|
+
if ((0, java_1.isIdentifier)(value)) {
|
|
407
|
+
parts.push(`${key}='${value.simpleName}'`);
|
|
408
|
+
}
|
|
409
|
+
else if ((0, java_1.isLiteral)(value)) {
|
|
410
|
+
parts.push(`${key}=${formatLiteralValue(value)}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return parts.length > 0 ? parts.join(' ') : undefined;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* LST Debug Printer - prints LST nodes in a readable format.
|
|
417
|
+
*
|
|
418
|
+
* Usage from within a visitor:
|
|
419
|
+
* ```typescript
|
|
420
|
+
* class MyVisitor extends JavaScriptVisitor<P> {
|
|
421
|
+
* private debug = new LstDebugPrinter({ includeCursorMessages: true });
|
|
422
|
+
*
|
|
423
|
+
* async visitMethodInvocation(mi: J.MethodInvocation, p: P) {
|
|
424
|
+
* this.debug.print(mi, this.cursor);
|
|
425
|
+
* return super.visitMethodInvocation(mi, p);
|
|
426
|
+
* }
|
|
427
|
+
* }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
class LstDebugPrinter {
|
|
431
|
+
constructor(options = {}) {
|
|
432
|
+
this.outputLines = [];
|
|
433
|
+
this.options = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Print a tree node with optional cursor context.
|
|
437
|
+
* @param tree The tree node to print
|
|
438
|
+
* @param cursor Optional cursor for context
|
|
439
|
+
* @param label Optional label to identify this debug output (shown as comment before output)
|
|
440
|
+
*/
|
|
441
|
+
print(tree, cursor, label) {
|
|
442
|
+
this.outputLines = [];
|
|
443
|
+
if (label) {
|
|
444
|
+
this.outputLines.push(`// ${label}`);
|
|
445
|
+
}
|
|
446
|
+
this.printNode(tree, cursor, 0);
|
|
447
|
+
this.flush();
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Print the cursor path from root to current position.
|
|
451
|
+
*/
|
|
452
|
+
printCursorPath(cursor) {
|
|
453
|
+
var _a;
|
|
454
|
+
this.outputLines = [];
|
|
455
|
+
this.outputLines.push('=== Cursor Path ===');
|
|
456
|
+
const path = [];
|
|
457
|
+
for (let c = cursor; c; c = c.parent) {
|
|
458
|
+
path.unshift(c);
|
|
459
|
+
}
|
|
460
|
+
for (let i = 0; i < path.length; i++) {
|
|
461
|
+
const c = path[i];
|
|
462
|
+
const indent = this.options.indent.repeat(i);
|
|
463
|
+
const kind = (_a = c.value) === null || _a === void 0 ? void 0 : _a.kind;
|
|
464
|
+
const typeName = shortTypeName(kind);
|
|
465
|
+
let line = `${indent}${typeName}`;
|
|
466
|
+
if (this.options.includeCursorMessages && c.messages.size > 0) {
|
|
467
|
+
line += ` [${formatCursorMessages(c)}]`;
|
|
468
|
+
}
|
|
469
|
+
this.outputLines.push(line);
|
|
470
|
+
}
|
|
471
|
+
this.flush();
|
|
472
|
+
}
|
|
473
|
+
printNode(node, cursor, depth) {
|
|
474
|
+
if (this.options.maxDepth >= 0 && depth > this.options.maxDepth) {
|
|
475
|
+
this.outputLines.push(`${this.indent(depth)}...`);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (node === null || node === undefined) {
|
|
479
|
+
this.outputLines.push(`${this.indent(depth)}null`);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
// Handle special types
|
|
483
|
+
if (this.isSpace(node)) {
|
|
484
|
+
this.outputLines.push(`${this.indent(depth)}${formatSpace(node)}`);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
if (this.isContainer(node)) {
|
|
488
|
+
this.printContainer(node, cursor, depth);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (this.isLeftPadded(node)) {
|
|
492
|
+
this.printLeftPadded(node, cursor, depth);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
if (this.isRightPadded(node)) {
|
|
496
|
+
this.printRightPadded(node, cursor, depth);
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if ((0, java_1.isJava)(node)) {
|
|
500
|
+
this.printJavaNode(node, cursor, depth);
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
// Primitive or unknown type
|
|
504
|
+
if (typeof node !== 'object') {
|
|
505
|
+
this.outputLines.push(`${this.indent(depth)}${JSON.stringify(node)}`);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
// Generic object - print as JSON-like
|
|
509
|
+
this.printGenericObject(node, depth);
|
|
510
|
+
}
|
|
511
|
+
printJavaNode(node, cursor, depth) {
|
|
512
|
+
var _a, _b;
|
|
513
|
+
const typeName = shortTypeName(node.kind);
|
|
514
|
+
let header = `${this.indent(depth)}${typeName}`;
|
|
515
|
+
// Add inline summary for certain types (Identifier, Literal)
|
|
516
|
+
const summary = getNodeSummary(node);
|
|
517
|
+
if (summary) {
|
|
518
|
+
header += ` ${summary}`;
|
|
519
|
+
}
|
|
520
|
+
// Add cursor messages if available
|
|
521
|
+
if (this.options.includeCursorMessages && cursor) {
|
|
522
|
+
const messages = formatCursorMessages(cursor);
|
|
523
|
+
if (messages !== '<no messages>') {
|
|
524
|
+
header += ` [${messages}]`;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
// Add ID if requested
|
|
528
|
+
if (this.options.includeIds && node.id) {
|
|
529
|
+
header += ` (id=${node.id.substring(0, 8)}...)`;
|
|
530
|
+
}
|
|
531
|
+
this.outputLines.push(header);
|
|
532
|
+
// Print prefix
|
|
533
|
+
if (node.prefix) {
|
|
534
|
+
this.outputLines.push(`${this.indent(depth + 1)}prefix: ${formatSpace(node.prefix)}`);
|
|
535
|
+
}
|
|
536
|
+
// Print markers if requested
|
|
537
|
+
if (this.options.includeMarkers && ((_b = (_a = node.markers) === null || _a === void 0 ? void 0 : _a.markers) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
538
|
+
this.outputLines.push(`${this.indent(depth + 1)}markers: [${node.markers.markers.map((m) => shortTypeName(m.kind)).join(', ')}]`);
|
|
539
|
+
}
|
|
540
|
+
// Print other properties
|
|
541
|
+
this.printNodeProperties(node, cursor, depth + 1);
|
|
542
|
+
}
|
|
543
|
+
printNodeProperties(node, cursor, depth) {
|
|
544
|
+
const excludedProps = new Set([
|
|
545
|
+
...EXCLUDED_PROPERTIES,
|
|
546
|
+
...this.options.excludeProperties,
|
|
547
|
+
'kind',
|
|
548
|
+
'id',
|
|
549
|
+
'prefix',
|
|
550
|
+
'markers',
|
|
551
|
+
]);
|
|
552
|
+
for (const [key, value] of Object.entries(node)) {
|
|
553
|
+
if (excludedProps.has(key))
|
|
554
|
+
continue;
|
|
555
|
+
if (value === undefined || value === null)
|
|
556
|
+
continue;
|
|
557
|
+
if (this.isSpace(value)) {
|
|
558
|
+
this.outputLines.push(`${this.indent(depth)}${key}: ${formatSpace(value)}`);
|
|
559
|
+
}
|
|
560
|
+
else if (this.isContainer(value)) {
|
|
561
|
+
this.outputLines.push(`${this.indent(depth)}${key}:`);
|
|
562
|
+
this.printContainer(value, undefined, depth + 1);
|
|
563
|
+
}
|
|
564
|
+
else if (this.isLeftPadded(value)) {
|
|
565
|
+
this.outputLines.push(`${this.indent(depth)}${key}:`);
|
|
566
|
+
this.printLeftPadded(value, undefined, depth + 1);
|
|
567
|
+
}
|
|
568
|
+
else if (this.isRightPadded(value)) {
|
|
569
|
+
this.outputLines.push(`${this.indent(depth)}${key}:`);
|
|
570
|
+
this.printRightPadded(value, undefined, depth + 1);
|
|
571
|
+
}
|
|
572
|
+
else if (Array.isArray(value)) {
|
|
573
|
+
if (value.length === 0) {
|
|
574
|
+
this.outputLines.push(`${this.indent(depth)}${key}: []`);
|
|
575
|
+
}
|
|
576
|
+
else if (value.every(v => this.isRightPadded(v))) {
|
|
577
|
+
this.outputLines.push(`${this.indent(depth)}${key}: [${value.length} RightPadded elements]`);
|
|
578
|
+
for (let i = 0; i < value.length; i++) {
|
|
579
|
+
this.outputLines.push(`${this.indent(depth + 1)}[${i}]:`);
|
|
580
|
+
this.printRightPadded(value[i], undefined, depth + 2);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
else if (value.every(v => (0, java_1.isJava)(v))) {
|
|
584
|
+
this.outputLines.push(`${this.indent(depth)}${key}: [${value.length} elements]`);
|
|
585
|
+
for (let i = 0; i < value.length; i++) {
|
|
586
|
+
this.outputLines.push(`${this.indent(depth + 1)}[${i}]:`);
|
|
587
|
+
this.printNode(value[i], undefined, depth + 2);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
this.outputLines.push(`${this.indent(depth)}${key}: [${value.length} items]`);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
else if ((0, java_1.isJava)(value)) {
|
|
595
|
+
this.outputLines.push(`${this.indent(depth)}${key}:`);
|
|
596
|
+
this.printNode(value, undefined, depth + 1);
|
|
597
|
+
}
|
|
598
|
+
else if (typeof value === 'object') {
|
|
599
|
+
// Skip complex objects that aren't J nodes
|
|
600
|
+
this.outputLines.push(`${this.indent(depth)}${key}: <object>`);
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
this.outputLines.push(`${this.indent(depth)}${key}: ${JSON.stringify(value)}`);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
printContainer(container, cursor, depth) {
|
|
608
|
+
var _a, _b;
|
|
609
|
+
const elemCount = (_b = (_a = container.elements) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
610
|
+
let header = `${this.indent(depth)}Container<${elemCount} elements>`;
|
|
611
|
+
if (this.options.includeCursorMessages && cursor) {
|
|
612
|
+
const messages = formatCursorMessages(cursor);
|
|
613
|
+
if (messages !== '<no messages>') {
|
|
614
|
+
header += ` [${messages}]`;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
this.outputLines.push(header);
|
|
618
|
+
this.outputLines.push(`${this.indent(depth + 1)}before: ${formatSpace(container.before)}`);
|
|
619
|
+
if (container.elements && container.elements.length > 0) {
|
|
620
|
+
this.outputLines.push(`${this.indent(depth + 1)}elements:`);
|
|
621
|
+
for (let i = 0; i < container.elements.length; i++) {
|
|
622
|
+
this.outputLines.push(`${this.indent(depth + 2)}[${i}]:`);
|
|
623
|
+
this.printRightPadded(container.elements[i], undefined, depth + 3);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
printLeftPadded(lp, cursor, depth) {
|
|
628
|
+
let header = `${this.indent(depth)}LeftPadded`;
|
|
629
|
+
if (this.options.includeCursorMessages && cursor) {
|
|
630
|
+
const messages = formatCursorMessages(cursor);
|
|
631
|
+
if (messages !== '<no messages>') {
|
|
632
|
+
header += ` [${messages}]`;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
this.outputLines.push(header);
|
|
636
|
+
this.outputLines.push(`${this.indent(depth + 1)}before: ${formatSpace(lp.before)}`);
|
|
637
|
+
if (lp.element !== undefined) {
|
|
638
|
+
if ((0, java_1.isJava)(lp.element)) {
|
|
639
|
+
this.outputLines.push(`${this.indent(depth + 1)}element:`);
|
|
640
|
+
this.printNode(lp.element, undefined, depth + 2);
|
|
641
|
+
}
|
|
642
|
+
else if (this.isSpace(lp.element)) {
|
|
643
|
+
this.outputLines.push(`${this.indent(depth + 1)}element: ${formatSpace(lp.element)}`);
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
this.outputLines.push(`${this.indent(depth + 1)}element: ${JSON.stringify(lp.element)}`);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
printRightPadded(rp, cursor, depth) {
|
|
651
|
+
let header = `${this.indent(depth)}RightPadded`;
|
|
652
|
+
if (this.options.includeCursorMessages && cursor) {
|
|
653
|
+
const messages = formatCursorMessages(cursor);
|
|
654
|
+
if (messages !== '<no messages>') {
|
|
655
|
+
header += ` [${messages}]`;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
this.outputLines.push(header);
|
|
659
|
+
if (rp.element !== undefined) {
|
|
660
|
+
if ((0, java_1.isJava)(rp.element)) {
|
|
661
|
+
this.outputLines.push(`${this.indent(depth + 1)}element:`);
|
|
662
|
+
this.printNode(rp.element, undefined, depth + 2);
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
this.outputLines.push(`${this.indent(depth + 1)}element: ${JSON.stringify(rp.element)}`);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
this.outputLines.push(`${this.indent(depth + 1)}after: ${formatSpace(rp.after)}`);
|
|
669
|
+
}
|
|
670
|
+
printGenericObject(obj, depth) {
|
|
671
|
+
this.outputLines.push(`${this.indent(depth)}{`);
|
|
672
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
673
|
+
if (typeof value === 'object' && value !== null) {
|
|
674
|
+
this.outputLines.push(`${this.indent(depth + 1)}${key}: <object>`);
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
this.outputLines.push(`${this.indent(depth + 1)}${key}: ${JSON.stringify(value)}`);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
this.outputLines.push(`${this.indent(depth)}}`);
|
|
681
|
+
}
|
|
682
|
+
isSpace(value) {
|
|
683
|
+
return value !== null &&
|
|
684
|
+
typeof value === 'object' &&
|
|
685
|
+
'whitespace' in value &&
|
|
686
|
+
'comments' in value &&
|
|
687
|
+
!('kind' in value);
|
|
688
|
+
}
|
|
689
|
+
isContainer(value) {
|
|
690
|
+
return value !== null &&
|
|
691
|
+
typeof value === 'object' &&
|
|
692
|
+
value.kind === java_1.J.Kind.Container;
|
|
693
|
+
}
|
|
694
|
+
isLeftPadded(value) {
|
|
695
|
+
return value !== null &&
|
|
696
|
+
typeof value === 'object' &&
|
|
697
|
+
value.kind === java_1.J.Kind.LeftPadded;
|
|
698
|
+
}
|
|
699
|
+
isRightPadded(value) {
|
|
700
|
+
return value !== null &&
|
|
701
|
+
typeof value === 'object' &&
|
|
702
|
+
value.kind === java_1.J.Kind.RightPadded;
|
|
703
|
+
}
|
|
704
|
+
indent(depth) {
|
|
705
|
+
return this.options.indent.repeat(depth);
|
|
706
|
+
}
|
|
707
|
+
flush() {
|
|
708
|
+
const output = this.outputLines.join('\n');
|
|
709
|
+
if (this.options.output === 'console') {
|
|
710
|
+
console.info(output);
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
fs.appendFileSync(this.options.output, output + '\n\n');
|
|
714
|
+
}
|
|
715
|
+
this.outputLines = [];
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
exports.LstDebugPrinter = LstDebugPrinter;
|
|
719
|
+
/**
|
|
720
|
+
* A visitor that prints the LST structure as it traverses.
|
|
721
|
+
* Useful for debugging the entire tree or a subtree.
|
|
722
|
+
*
|
|
723
|
+
* Usage:
|
|
724
|
+
* ```typescript
|
|
725
|
+
* const debugVisitor = new LstDebugVisitor({ maxDepth: 3 });
|
|
726
|
+
* await debugVisitor.visit(tree, ctx);
|
|
727
|
+
* ```
|
|
728
|
+
*/
|
|
729
|
+
class LstDebugVisitor extends visitor_1.JavaScriptVisitor {
|
|
730
|
+
constructor(options = {}, config = {}) {
|
|
731
|
+
var _a, _b;
|
|
732
|
+
super();
|
|
733
|
+
this.depth = 0;
|
|
734
|
+
this.printer = new LstDebugPrinter(options);
|
|
735
|
+
this.printPreVisit = (_a = config.printPreVisit) !== null && _a !== void 0 ? _a : true;
|
|
736
|
+
this.printPostVisit = (_b = config.printPostVisit) !== null && _b !== void 0 ? _b : false;
|
|
737
|
+
}
|
|
738
|
+
preVisit(tree, _p) {
|
|
739
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
740
|
+
if (this.printPreVisit) {
|
|
741
|
+
const typeName = shortTypeName(tree.kind);
|
|
742
|
+
const indent = ' '.repeat(this.depth);
|
|
743
|
+
const messages = formatCursorMessages(this.cursor);
|
|
744
|
+
const prefix = formatSpace(tree.prefix);
|
|
745
|
+
const summary = getNodeSummary(tree);
|
|
746
|
+
const propPath = findPropertyPath(this.cursor);
|
|
747
|
+
let line = indent;
|
|
748
|
+
if (propPath) {
|
|
749
|
+
line += `${propPath}: `;
|
|
750
|
+
}
|
|
751
|
+
line += `${typeName}{`;
|
|
752
|
+
if (summary) {
|
|
753
|
+
line += `${summary} `;
|
|
754
|
+
}
|
|
755
|
+
line += `prefix=${prefix}}`;
|
|
756
|
+
console.info(line);
|
|
757
|
+
// Show cursor messages on a separate indented line
|
|
758
|
+
if (messages !== '<no messages>') {
|
|
759
|
+
console.info(`${indent} ⤷ ${messages}`);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
this.depth++;
|
|
763
|
+
return tree;
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
postVisit(tree, _p) {
|
|
767
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
768
|
+
this.depth--;
|
|
769
|
+
if (this.printPostVisit) {
|
|
770
|
+
const typeName = shortTypeName(tree.kind);
|
|
771
|
+
const indent = ' '.repeat(this.depth);
|
|
772
|
+
console.info(`${indent}← ${typeName}`);
|
|
773
|
+
}
|
|
774
|
+
return tree;
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
visitContainer(container, p) {
|
|
778
|
+
const _super = Object.create(null, {
|
|
779
|
+
visitContainer: { get: () => super.visitContainer }
|
|
780
|
+
});
|
|
781
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
782
|
+
if (this.printPreVisit) {
|
|
783
|
+
const indent = ' '.repeat(this.depth);
|
|
784
|
+
const messages = formatCursorMessages(this.cursor);
|
|
785
|
+
const before = formatSpace(container.before);
|
|
786
|
+
// Pass container as the child since cursor.value is the parent node
|
|
787
|
+
const propPath = findPropertyPath(this.cursor, container);
|
|
788
|
+
let line = indent;
|
|
789
|
+
if (propPath) {
|
|
790
|
+
line += `${propPath}: `;
|
|
791
|
+
}
|
|
792
|
+
line += `Container<${container.elements.length}>{before=${before}}`;
|
|
793
|
+
console.info(line);
|
|
794
|
+
if (messages !== '<no messages>') {
|
|
795
|
+
console.info(`${indent} ⤷ ${messages}`);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
this.depth++;
|
|
799
|
+
const result = yield _super.visitContainer.call(this, container, p);
|
|
800
|
+
this.depth--;
|
|
801
|
+
return result;
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
visitLeftPadded(left, p) {
|
|
805
|
+
const _super = Object.create(null, {
|
|
806
|
+
visitLeftPadded: { get: () => super.visitLeftPadded }
|
|
807
|
+
});
|
|
808
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
809
|
+
if (this.printPreVisit) {
|
|
810
|
+
const indent = ' '.repeat(this.depth);
|
|
811
|
+
const messages = formatCursorMessages(this.cursor);
|
|
812
|
+
const before = formatSpace(left.before);
|
|
813
|
+
// Pass left as the child since cursor.value is the parent node
|
|
814
|
+
const propPath = findPropertyPath(this.cursor, left);
|
|
815
|
+
let line = indent;
|
|
816
|
+
if (propPath) {
|
|
817
|
+
line += `${propPath}: `;
|
|
818
|
+
}
|
|
819
|
+
line += `LeftPadded{before=${before}`;
|
|
820
|
+
// Show element value if it's a primitive (string, number, boolean)
|
|
821
|
+
if (left.element !== null && left.element !== undefined) {
|
|
822
|
+
const elemType = typeof left.element;
|
|
823
|
+
if (elemType === 'string' || elemType === 'number' || elemType === 'boolean') {
|
|
824
|
+
line += ` element=${JSON.stringify(left.element)}`;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
line += '}';
|
|
828
|
+
console.info(line);
|
|
829
|
+
if (messages !== '<no messages>') {
|
|
830
|
+
console.info(`${indent} ⤷ ${messages}`);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
this.depth++;
|
|
834
|
+
const result = yield _super.visitLeftPadded.call(this, left, p);
|
|
835
|
+
this.depth--;
|
|
836
|
+
return result;
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
visitRightPadded(right, p) {
|
|
840
|
+
const _super = Object.create(null, {
|
|
841
|
+
visitRightPadded: { get: () => super.visitRightPadded }
|
|
842
|
+
});
|
|
843
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
844
|
+
if (this.printPreVisit) {
|
|
845
|
+
const indent = ' '.repeat(this.depth);
|
|
846
|
+
const messages = formatCursorMessages(this.cursor);
|
|
847
|
+
const after = formatSpace(right.after);
|
|
848
|
+
// Pass right as the child since cursor.value is the parent node
|
|
849
|
+
const propPath = findPropertyPath(this.cursor, right);
|
|
850
|
+
let line = indent;
|
|
851
|
+
if (propPath) {
|
|
852
|
+
line += `${propPath}: `;
|
|
853
|
+
}
|
|
854
|
+
line += `RightPadded{after=${after}`;
|
|
855
|
+
// Show element value if it's a primitive (string, number, boolean)
|
|
856
|
+
if (right.element !== null && right.element !== undefined) {
|
|
857
|
+
const elemType = typeof right.element;
|
|
858
|
+
if (elemType === 'string' || elemType === 'number' || elemType === 'boolean') {
|
|
859
|
+
line += ` element=${JSON.stringify(right.element)}`;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
line += '}';
|
|
863
|
+
console.info(line);
|
|
864
|
+
if (messages !== '<no messages>') {
|
|
865
|
+
console.info(`${indent} ⤷ ${messages}`);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
this.depth++;
|
|
869
|
+
const result = yield _super.visitRightPadded.call(this, right, p);
|
|
870
|
+
this.depth--;
|
|
871
|
+
return result;
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
exports.LstDebugVisitor = LstDebugVisitor;
|
|
876
|
+
/**
|
|
877
|
+
* Convenience function to print a tree node.
|
|
878
|
+
* @param tree The tree node to print
|
|
879
|
+
* @param cursor Optional cursor for context
|
|
880
|
+
* @param label Optional label to identify this debug output
|
|
881
|
+
* @param options Optional debug options
|
|
882
|
+
*/
|
|
883
|
+
function debugPrint(tree, cursor, label, options) {
|
|
884
|
+
new LstDebugPrinter(options).print(tree, cursor, label);
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Convenience function to print cursor path.
|
|
888
|
+
*/
|
|
889
|
+
function debugPrintCursorPath(cursor, options) {
|
|
890
|
+
new LstDebugPrinter(options).printCursorPath(cursor);
|
|
891
|
+
}
|
|
892
|
+
//# sourceMappingURL=tree-debug.js.map
|