pi-hashline-edit-pro 7.0.0 → 7.1.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.
@@ -25,113 +25,83 @@ export function extractJava(
25
25
  const child = node.namedChild(i);
26
26
  if (!child) continue;
27
27
 
28
- const symbol = extractJavaTopLevel(child, source, depth, MAX_DEPTH);
28
+ const symbol = extractJavaType(child, source, depth, MAX_DEPTH);
29
29
  if (symbol) results.push(symbol);
30
30
  }
31
31
 
32
32
  return results;
33
33
  }
34
34
 
35
- function extractJavaType(
36
- node: Node,
37
- source: string,
38
- depth: number,
39
- MAX_DEPTH: number,
40
- ): SymbolInfo | null {
41
- switch (node.type) {
42
- case "class_declaration":
43
- case "interface_declaration":
44
- case "enum_declaration":
45
- case "record_declaration":
46
- case "annotation_type_declaration":
47
- return extractJavaTypeDeclaration(node, source, depth, MAX_DEPTH);
48
- default:
49
- return null;
35
+ const JAVA_TYPE_LABELS: Record<string, string> = {
36
+ class_declaration: "class",
37
+ interface_declaration: "interface",
38
+ enum_declaration: "enum",
39
+ record_declaration: "record",
40
+ annotation_type_declaration: "annotation",
41
+ };
42
+
43
+ function fieldText(node: Node, field: string, source: string): string | undefined {
44
+ const child = node.childForFieldName(field);
45
+ return child === null ? undefined : source.slice(child.startIndex, child.endIndex);
46
+ }
47
+
48
+ function childText(node: Node, childType: string, source: string): string | undefined {
49
+ for (let index = 0; index < node.namedChildCount; index++) {
50
+ const child = node.namedChild(index);
51
+ if (child !== null && child.type === childType) return source.slice(child.startIndex, child.endIndex);
50
52
  }
53
+ return undefined;
51
54
  }
52
55
 
53
- function extractJavaTopLevel(
54
- child: Node,
56
+ const JAVA_SKIPPED_TYPES = new Set(["annotation", "marker_annotation", "comment", "line_comment", "block_comment"]);
57
+
58
+ function firstDeclaredTokenRow(node: Node): number | undefined {
59
+ for (let index = 0; index < node.childCount; index++) {
60
+ const child = node.child(index);
61
+ if (child === null || JAVA_SKIPPED_TYPES.has(child.type)) continue;
62
+ if (child.type === "modifiers") {
63
+ for (let tokenIndex = 0; tokenIndex < child.childCount; tokenIndex++) {
64
+ const token = child.child(tokenIndex);
65
+ if (token === null || JAVA_SKIPPED_TYPES.has(token.type)) continue;
66
+ return token.startPosition.row + 1;
67
+ }
68
+ continue;
69
+ }
70
+ return child.startPosition.row + 1;
71
+ }
72
+ return undefined;
73
+ }
74
+
75
+ function declarationLine(node: Node): number {
76
+ return firstDeclaredTokenRow(node) ?? node.startPosition.row + 1;
77
+ }
78
+
79
+ function extractJavaType(
80
+ node: Node,
55
81
  source: string,
56
82
  depth: number,
57
83
  MAX_DEPTH: number,
58
84
  ): SymbolInfo | null {
59
- return extractJavaType(child, source, depth, MAX_DEPTH);
85
+ if (JAVA_TYPE_LABELS[node.type] === undefined) return null;
86
+ return extractJavaTypeDeclaration(node, source, depth, MAX_DEPTH);
60
87
  }
61
88
 
62
89
  function extractJavaTypeDeclaration(
63
- child: Node,
90
+ node: Node,
64
91
  source: string,
65
92
  depth: number,
66
93
  MAX_DEPTH: number,
67
- ): SymbolInfo | null {
68
- let typeName = "<unknown>";
69
- let typeLabel = "class";
70
- const modifiers: string[] = [];
71
- let superClass: string | undefined;
72
- const interfaces: string[] = [];
73
- const extendsInterfaces: string[] = [];
74
-
75
- if (child.type === "interface_declaration") typeLabel = "interface";
76
- else if (child.type === "enum_declaration") typeLabel = "enum";
77
- else if (child.type === "record_declaration") typeLabel = "record";
78
- else if (child.type === "annotation_type_declaration") typeLabel = "annotation";
79
-
80
- for (let j = 0; j < child.namedChildCount; j++) {
81
- const c = child.namedChild(j);
82
- if (!c) continue;
83
-
84
- if (c.type === "modifiers") {
85
- for (let k = 0; k < c.namedChildCount; k++) {
86
- const sub = c.namedChild(k);
87
- if (sub && sub.type !== "annotation") {
88
- modifiers.push(source.slice(sub.startIndex, sub.endIndex));
89
- }
90
- }
91
- } else if (c.type === "identifier") {
92
- typeName = source.slice(c.startIndex, c.endIndex);
93
- } else if (c.type === "superclass") {
94
- for (let k = 0; k < c.namedChildCount; k++) {
95
- const sub = c.namedChild(k);
96
- if (sub && sub.type !== "extends") {
97
- superClass = source.slice(sub.startIndex, sub.endIndex);
98
- }
99
- }
100
- } else if (c.type === "super_interfaces") {
101
- for (let k = 0; k < c.namedChildCount; k++) {
102
- const sub = c.namedChild(k);
103
- if (sub && sub.type !== "implements") {
104
- interfaces.push(source.slice(sub.startIndex, sub.endIndex));
105
- }
106
- }
107
- } else if (c.type === "extends_interfaces") {
108
- for (let k = 0; k < c.namedChildCount; k++) {
109
- const sub = c.namedChild(k);
110
- if (sub && sub.type !== "extends") {
111
- extendsInterfaces.push(source.slice(sub.startIndex, sub.endIndex));
112
- }
113
- }
114
- }
115
- }
116
-
117
- const [sl, el] = [child.startPosition.row + 1, child.endPosition.row + 1];
118
- const detailParts: string[] = [];
119
- if (modifiers.length > 0) detailParts.push(modifiers.join(" "));
120
- if (superClass) detailParts.push("extends " + superClass);
121
- if (interfaces.length > 0) detailParts.push("implements " + interfaces.join(", "));
122
- if (extendsInterfaces.length > 0) detailParts.push("extends " + extendsInterfaces.join(", "));
123
-
94
+ ): SymbolInfo {
124
95
  const symbol: SymbolInfo = {
125
- name: typeName,
126
- type: typeLabel,
127
- startLine: sl,
128
- endLine: el,
129
- detail: detailParts.length > 0 ? detailParts.join(" ") : undefined,
96
+ name: fieldText(node, "name", source) ?? "<unknown>",
97
+ type: JAVA_TYPE_LABELS[node.type] ?? "class",
98
+ startLine: declarationLine(node),
99
+ endLine: node.endPosition.row + 1,
130
100
  };
131
101
 
132
102
  if (depth < MAX_DEPTH) {
133
- const body = findClassBody(child);
134
- if (body) {
103
+ const body = findClassBody(node);
104
+ if (body !== null) {
135
105
  const children = extractJavaClassBody(body, source, depth + 1, MAX_DEPTH);
136
106
  if (children.length > 0) symbol.children = children;
137
107
  }
@@ -142,15 +112,15 @@ function extractJavaTypeDeclaration(
142
112
 
143
113
  function findClassBody(node: Node): Node | null {
144
114
  for (let i = 0; i < node.namedChildCount; i++) {
145
- const c = node.namedChild(i);
146
- if (!c) continue;
115
+ const child = node.namedChild(i);
116
+ if (child === null) continue;
147
117
  if (
148
- c.type === "class_body" ||
149
- c.type === "enum_body" ||
150
- c.type === "interface_body" ||
151
- c.type === "annotation_type_body"
118
+ child.type === "class_body" ||
119
+ child.type === "enum_body" ||
120
+ child.type === "interface_body" ||
121
+ child.type === "annotation_type_body"
152
122
  ) {
153
- return c;
123
+ return child;
154
124
  }
155
125
  }
156
126
  return null;
@@ -166,287 +136,132 @@ function extractJavaClassBody(
166
136
 
167
137
  for (let i = 0; i < body.namedChildCount; i++) {
168
138
  const child = body.namedChild(i);
169
- if (!child) continue;
170
-
171
- switch (child.type) {
172
- case "method_declaration": {
173
- const method = extractJavaMethod(child, source);
174
- if (method) results.push(method);
175
- break;
176
- }
177
- case "constructor_declaration": {
178
- const ctor = extractJavaConstructor(child, source);
179
- if (ctor) results.push(ctor);
180
- break;
181
- }
182
- case "field_declaration": {
183
- const fields = extractJavaFields(child, source);
184
- results.push(...fields);
185
- break;
186
- }
187
- case "class_declaration":
188
- case "interface_declaration":
189
- case "enum_declaration":
190
- case "record_declaration":
191
- case "annotation_type_declaration": {
192
- const type = extractJavaTypeDeclaration(child, source, depth, MAX_DEPTH);
193
- if (type) results.push(type);
194
- break;
195
- }
196
- case "enum_constant": {
197
- const ec = extractJavaEnumConstant(child, source);
198
- if (ec) results.push(ec);
199
- break;
200
- }
201
- case "static_initializer": {
202
- const [sl, el] = [child.startPosition.row + 1, child.endPosition.row + 1];
203
- results.push({ name: "static", type: "static_initializer", startLine: sl, endLine: el });
204
- break;
205
- }
206
- }
139
+ if (child === null) continue;
140
+ results.push(...extractJavaMember(child, source, depth, MAX_DEPTH));
207
141
  }
208
142
 
209
143
  return results;
210
144
  }
211
145
 
212
- function extractModifiers(node: Node, source: string): string[] {
213
- const mods: string[] = [];
214
- for (let i = 0; i < node.namedChildCount; i++) {
215
- const c = node.namedChild(i);
216
- if (!c) continue;
217
- if (c.type !== "annotation") {
218
- mods.push(source.slice(c.startIndex, c.endIndex));
219
- }
146
+ function extractJavaMember(
147
+ node: Node,
148
+ source: string,
149
+ depth: number,
150
+ MAX_DEPTH: number,
151
+ ): SymbolInfo[] {
152
+ switch (node.type) {
153
+ case "method_declaration":
154
+ return [extractJavaMethod(node, source)];
155
+ case "constructor_declaration":
156
+ case "compact_constructor_declaration":
157
+ return [extractJavaConstructor(node, source)];
158
+ case "field_declaration":
159
+ case "constant_declaration":
160
+ return extractJavaFields(node, source);
161
+ case "class_declaration":
162
+ case "interface_declaration":
163
+ case "enum_declaration":
164
+ case "record_declaration":
165
+ case "annotation_type_declaration":
166
+ return [extractJavaTypeDeclaration(node, source, depth, MAX_DEPTH)];
167
+ case "enum_constant":
168
+ return [extractJavaEnumConstant(node, source)];
169
+ case "annotation_type_element_declaration":
170
+ return [extractJavaAnnotationElement(node, source)];
171
+ case "enum_body_declarations":
172
+ return extractJavaClassBody(node, source, depth, MAX_DEPTH);
173
+ case "static_initializer":
174
+ return [{
175
+ name: "static",
176
+ type: "static_initializer",
177
+ startLine: node.startPosition.row + 1,
178
+ endLine: node.endPosition.row + 1,
179
+ }];
180
+ default:
181
+ return [];
220
182
  }
221
- return mods;
222
183
  }
223
184
 
224
185
  function extractJavaMethod(
225
- child: Node,
186
+ node: Node,
226
187
  source: string,
227
- ): SymbolInfo | null {
228
- let methodName = "<unknown>";
229
- const modifiers: string[] = [];
230
- let returnType: string | undefined;
231
- let params: string | undefined;
232
- let typeParams: string | undefined;
233
-
234
- for (let j = 0; j < child.namedChildCount; j++) {
235
- const c = child.namedChild(j);
236
- if (!c) continue;
237
-
238
- if (c.type === "modifiers") {
239
- for (let k = 0; k < c.namedChildCount; k++) {
240
- const sub = c.namedChild(k);
241
- if (sub && sub.type !== "annotation") {
242
- modifiers.push(source.slice(sub.startIndex, sub.endIndex));
243
- }
244
- }
245
- } else if (c.type === "_method_header") {
246
- for (let k = 0; k < c.namedChildCount; k++) {
247
- const sub = c.namedChild(k);
248
- if (!sub) continue;
249
-
250
- if (sub.type === "type_parameters") {
251
- typeParams = source.slice(sub.startIndex, sub.endIndex);
252
- } else if (sub.type === "_method_declarator") {
253
- for (let m = 0; m < sub.namedChildCount; m++) {
254
- const decl = sub.namedChild(m);
255
- if (!decl) continue;
256
- if (decl.type === "identifier") {
257
- methodName = source.slice(decl.startIndex, decl.endIndex);
258
- } else if (decl.type === "formal_parameters") {
259
- params = source.slice(decl.startIndex, decl.endIndex);
260
- }
261
- }
262
- } else if (sub.type !== "type_parameters" && sub.type !== "_method_declarator" && sub.type !== "throws") {
263
- returnType = source.slice(sub.startIndex, sub.endIndex);
264
- }
265
- }
266
- }
267
- }
268
-
269
- const [sl, el] = [child.startPosition.row + 1, child.endPosition.row + 1];
270
- const detailParts: string[] = [];
271
- if (modifiers.length > 0) detailParts.push(modifiers.join(" "));
272
- if (typeParams) detailParts.push(typeParams);
273
- if (returnType) detailParts.push(returnType);
274
- if (params) detailParts.push(params);
275
-
188
+ ): SymbolInfo {
276
189
  return {
277
- name: methodName,
190
+ name: fieldText(node, "name", source) ?? "<unknown>",
278
191
  type: "method",
279
- startLine: sl,
280
- endLine: el,
281
- detail: detailParts.length > 0 ? detailParts.join(" ") : undefined,
192
+ startLine: declarationLine(node),
193
+ endLine: node.endPosition.row + 1,
282
194
  };
283
195
  }
284
196
 
285
197
  function extractJavaConstructor(
286
- child: Node,
198
+ node: Node,
287
199
  source: string,
288
- ): SymbolInfo | null {
289
- let ctorName = "<unknown>";
290
- const modifiers: string[] = [];
291
- let params: string | undefined;
292
- let typeParams: string | undefined;
293
-
294
- for (let j = 0; j < child.namedChildCount; j++) {
295
- const c = child.namedChild(j);
296
- if (!c) continue;
297
-
298
- if (c.type === "modifiers") {
299
- for (let k = 0; k < c.namedChildCount; k++) {
300
- const sub = c.namedChild(k);
301
- if (sub && sub.type !== "annotation") {
302
- modifiers.push(source.slice(sub.startIndex, sub.endIndex));
303
- }
304
- }
305
- } else if (c.type === "_constructor_declarator") {
306
- for (let k = 0; k < c.namedChildCount; k++) {
307
- const sub = c.namedChild(k);
308
- if (!sub) continue;
309
- if (sub.type === "type_parameters") {
310
- typeParams = source.slice(sub.startIndex, sub.endIndex);
311
- } else if (sub.type === "identifier") {
312
- ctorName = source.slice(sub.startIndex, sub.endIndex);
313
- } else if (sub.type === "formal_parameters") {
314
- params = source.slice(sub.startIndex, sub.endIndex);
315
- }
316
- }
317
- }
318
- }
319
-
320
- const [sl, el] = [child.startPosition.row + 1, child.endPosition.row + 1];
321
- const detailParts: string[] = [];
322
- if (modifiers.length > 0) detailParts.push(modifiers.join(" "));
323
- if (typeParams) detailParts.push(typeParams);
324
- if (params) detailParts.push(params);
325
-
200
+ ): SymbolInfo {
326
201
  return {
327
- name: ctorName,
202
+ name: fieldText(node, "name", source) ?? childText(node, "identifier", source) ?? "<unknown>",
328
203
  type: "constructor",
329
- startLine: sl,
330
- endLine: el,
331
- detail: detailParts.length > 0 ? detailParts.join(" ") : undefined,
204
+ startLine: declarationLine(node),
205
+ endLine: node.endPosition.row + 1,
332
206
  };
333
207
  }
334
208
 
335
209
  function extractJavaFields(
336
- child: Node,
210
+ node: Node,
337
211
  source: string,
338
212
  ): SymbolInfo[] {
339
213
  const results: SymbolInfo[] = [];
340
- const modifiers: string[] = [];
341
- let fieldType: string | undefined;
342
-
343
- for (let j = 0; j < child.namedChildCount; j++) {
344
- const c = child.namedChild(j);
345
- if (!c) continue;
346
-
347
- if (c.type === "modifiers") {
348
- for (let k = 0; k < c.namedChildCount; k++) {
349
- const sub = c.namedChild(k);
350
- if (sub && sub.type !== "annotation") {
351
- modifiers.push(source.slice(sub.startIndex, sub.endIndex));
352
- }
353
- }
354
- } else if (c.type === "_unannotated_type" || c.type === "type") {
355
- fieldType = source.slice(c.startIndex, c.endIndex);
356
- } else if (c.type === "_variable_declarator_list") {
357
- for (let k = 0; k < c.namedChildCount; k++) {
358
- const decl = c.namedChild(k);
359
- if (!decl) continue;
360
- if (decl.type === "variable_declarator") {
361
- const field = extractJavaVariableDeclarator(decl, source, modifiers, fieldType);
362
- if (field) results.push(field);
363
- }
364
- }
365
- }
214
+ const fieldStartLine = declarationLine(node);
215
+
216
+ for (let i = 0; i < node.namedChildCount; i++) {
217
+ const declarator = node.namedChild(i);
218
+ if (declarator === null || declarator.type !== "variable_declarator") continue;
219
+
220
+ const declaratorStartLine = declarationLine(declarator);
221
+ results.push({
222
+ name: fieldText(declarator, "name", source) ?? "<unknown>",
223
+ type: "field",
224
+ startLine: results.length === 0 ? Math.min(fieldStartLine, declaratorStartLine) : declaratorStartLine,
225
+ endLine: declarator.endPosition.row + 1,
226
+ });
366
227
  }
367
228
 
368
229
  return results;
369
230
  }
370
231
 
371
- function extractJavaVariableDeclarator(
232
+ function extractJavaEnumConstant(
372
233
  node: Node,
373
234
  source: string,
374
- modifiers: string[],
375
- fieldType: string | undefined,
376
- ): SymbolInfo | null {
377
- let fieldName = "<unknown>";
378
- let fieldValue: string | undefined;
379
-
380
- for (let i = 0; i < node.namedChildCount; i++) {
381
- const c = node.namedChild(i);
382
- if (!c) continue;
383
-
384
- if (c.type === "_variable_declarator_id") {
385
- for (let j = 0; j < c.namedChildCount; j++) {
386
- const sub = c.namedChild(j);
387
- if (sub && sub.type === "identifier") {
388
- fieldName = source.slice(sub.startIndex, sub.endIndex);
389
- }
390
- }
391
- } else if (c.type === "=") {
392
- for (let j = 0; j < c.namedChildCount; j++) {
393
- const sub = c.namedChild(j);
394
- if (sub) {
395
- fieldValue = source.slice(sub.startIndex, sub.endIndex);
396
- }
397
- }
398
- }
399
- }
400
-
401
- const [sl, el] = [node.startPosition.row + 1, node.endPosition.row + 1];
402
- const detailParts: string[] = [];
403
- if (modifiers.length > 0) detailParts.push(modifiers.join(" "));
404
- if (fieldType) detailParts.push(fieldType);
405
- if (fieldValue) detailParts.push("= " + fieldValue);
406
-
235
+ ): SymbolInfo {
407
236
  return {
408
- name: fieldName,
409
- type: "field",
410
- startLine: sl,
411
- endLine: el,
412
- detail: detailParts.length > 0 ? detailParts.join(" ") : undefined,
237
+ name: fieldText(node, "name", source) ?? "<unknown>",
238
+ type: "enum_constant",
239
+ startLine: declarationLine(node),
240
+ endLine: node.endPosition.row + 1,
413
241
  };
414
242
  }
415
243
 
416
- function extractJavaEnumConstant(
417
- child: Node,
244
+ function extractJavaAnnotationElement(
245
+ node: Node,
418
246
  source: string,
419
- ): SymbolInfo | null {
420
- let constName = "<unknown>";
421
- let constArgs: string | undefined;
422
-
423
- for (let j = 0; j < child.namedChildCount; j++) {
424
- const c = child.namedChild(j);
425
- if (!c) continue;
426
-
427
- if (c.type === "identifier") {
428
- constName = source.slice(c.startIndex, c.endIndex);
429
- } else if (c.type === "argument_list") {
430
- constArgs = source.slice(c.startIndex, c.endIndex);
431
- }
432
- }
433
-
434
- const [sl, el] = [child.startPosition.row + 1, child.endPosition.row + 1];
435
- const detailParts: string[] = [];
436
- if (constArgs) detailParts.push(constArgs);
437
-
247
+ ): SymbolInfo {
438
248
  return {
439
- name: constName,
440
- type: "enum_constant",
441
- startLine: sl,
442
- endLine: el,
443
- detail: detailParts.length > 0 ? detailParts.join(" ") : undefined,
249
+ name: fieldText(node, "name", source) ?? "<unknown>",
250
+ type: "element",
251
+ startLine: declarationLine(node),
252
+ endLine: node.endPosition.row + 1,
444
253
  };
445
254
  }
446
255
 
256
+ function importIsStatic(declaration: string): boolean {
257
+ const withoutComments = declaration.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/\/\/[^\n]*/g, " ");
258
+ return /^\s*import\s+static\b/.test(withoutComments);
259
+ }
260
+
447
261
  /**
448
262
  * Extract Java imports.
449
263
  */
264
+
450
265
  export function extractJavaImports(
451
266
  node: Node,
452
267
  source: string,
@@ -459,16 +274,14 @@ export function extractJavaImports(
459
274
 
460
275
  if (child.type === "import_declaration") {
461
276
  let importSource = "";
462
- let isStatic = false;
277
+ const isStatic = importIsStatic(source.slice(child.startIndex, child.endIndex));
463
278
  let isWildcard = false;
464
279
 
465
280
  for (let j = 0; j < child.namedChildCount; j++) {
466
281
  const c = child.namedChild(j);
467
282
  if (!c) continue;
468
283
 
469
- if (c.type === "static" || source.slice(c.startIndex, c.endIndex) === "static") {
470
- isStatic = true;
471
- } else if (c.type === "asterisk") {
284
+ if (c.type === "asterisk") {
472
285
  isWildcard = true;
473
286
  } else if (c.type === "scoped_identifier" || c.type === "identifier") {
474
287
  importSource = source.slice(c.startIndex, c.endIndex);