@g1cloud/api-gen 1.0.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/.claude/settings.local.json +22 -0
- package/CLAUDE.md +63 -0
- package/README.md +379 -0
- package/dist/analyzer/controllerAnalyzer.d.ts +20 -0
- package/dist/analyzer/controllerAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/controllerAnalyzer.js +101 -0
- package/dist/analyzer/controllerAnalyzer.js.map +1 -0
- package/dist/analyzer/parameterAnalyzer.d.ts +19 -0
- package/dist/analyzer/parameterAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/parameterAnalyzer.js +207 -0
- package/dist/analyzer/parameterAnalyzer.js.map +1 -0
- package/dist/analyzer/responseAnalyzer.d.ts +12 -0
- package/dist/analyzer/responseAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/responseAnalyzer.js +116 -0
- package/dist/analyzer/responseAnalyzer.js.map +1 -0
- package/dist/analyzer/schemaGenerator.d.ts +6 -0
- package/dist/analyzer/schemaGenerator.d.ts.map +1 -0
- package/dist/analyzer/schemaGenerator.js +347 -0
- package/dist/analyzer/schemaGenerator.js.map +1 -0
- package/dist/analyzer/securityAnalyzer.d.ts +6 -0
- package/dist/analyzer/securityAnalyzer.d.ts.map +1 -0
- package/dist/analyzer/securityAnalyzer.js +177 -0
- package/dist/analyzer/securityAnalyzer.js.map +1 -0
- package/dist/generator/openapiGenerator.d.ts +14 -0
- package/dist/generator/openapiGenerator.d.ts.map +1 -0
- package/dist/generator/openapiGenerator.js +340 -0
- package/dist/generator/openapiGenerator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +61 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +199 -0
- package/dist/lib.js.map +1 -0
- package/dist/mcp-server.d.ts +9 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +257 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp-server.mjs +45586 -0
- package/dist/parser/astAnalyzer.d.ts +87 -0
- package/dist/parser/astAnalyzer.d.ts.map +1 -0
- package/dist/parser/astAnalyzer.js +321 -0
- package/dist/parser/astAnalyzer.js.map +1 -0
- package/dist/parser/javaParser.d.ts +10 -0
- package/dist/parser/javaParser.d.ts.map +1 -0
- package/dist/parser/javaParser.js +805 -0
- package/dist/parser/javaParser.js.map +1 -0
- package/dist/types/index.d.ts +217 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/examples/CreateUserRequest.java +80 -0
- package/examples/DepartmentDTO.java +45 -0
- package/examples/Filter.java +39 -0
- package/examples/PaginatedList.java +71 -0
- package/examples/ProductController.java +136 -0
- package/examples/ProductDTO.java +129 -0
- package/examples/RoleDTO.java +47 -0
- package/examples/SearchParam.java +55 -0
- package/examples/Sort.java +70 -0
- package/examples/UpdateUserRequest.java +74 -0
- package/examples/UserController.java +98 -0
- package/examples/UserDTO.java +119 -0
- package/package.json +51 -0
- package/prompt/01_Initial.md +358 -0
- package/prompt/02_/354/266/224/352/260/200.md +31 -0
- package/src/analyzer/controllerAnalyzer.ts +125 -0
- package/src/analyzer/parameterAnalyzer.ts +259 -0
- package/src/analyzer/responseAnalyzer.ts +142 -0
- package/src/analyzer/schemaGenerator.ts +412 -0
- package/src/analyzer/securityAnalyzer.ts +200 -0
- package/src/generator/openapiGenerator.ts +378 -0
- package/src/index.ts +212 -0
- package/src/lib.ts +240 -0
- package/src/mcp-server.ts +310 -0
- package/src/parser/astAnalyzer.ts +373 -0
- package/src/parser/javaParser.ts +901 -0
- package/src/types/index.ts +238 -0
- package/test-boolean.yaml +607 -0
- package/test-filter.yaml +576 -0
- package/test-inner.ts +59 -0
- package/test-output.yaml +650 -0
- package/test-paginated.yaml +585 -0
- package/tsconfig.json +20 -0
- package/tsup.config.ts +30 -0
|
@@ -0,0 +1,805 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.JavaFileParser = void 0;
|
|
37
|
+
exports.parseJavaSource = parseJavaSource;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const java_parser_1 = require("java-parser");
|
|
41
|
+
/**
|
|
42
|
+
* Extract Javadoc comments from source code
|
|
43
|
+
*/
|
|
44
|
+
function extractJavadocs(content) {
|
|
45
|
+
const javadocs = new Map();
|
|
46
|
+
const javadocRegex = /\/\*\*[\s\S]*?\*\//g;
|
|
47
|
+
let match;
|
|
48
|
+
while ((match = javadocRegex.exec(content)) !== null) {
|
|
49
|
+
const javadocText = match[0];
|
|
50
|
+
// Count newlines to find the end line of the javadoc
|
|
51
|
+
const beforeMatch = content.substring(0, match.index + javadocText.length);
|
|
52
|
+
const endLine = beforeMatch.split('\n').length;
|
|
53
|
+
// Parse the javadoc content
|
|
54
|
+
const parsedJavadoc = parseJavadocContent(javadocText);
|
|
55
|
+
if (parsedJavadoc.description || parsedJavadoc.info.returns || Object.keys(parsedJavadoc.info.params).length > 0) {
|
|
56
|
+
javadocs.set(endLine, parsedJavadoc);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return javadocs;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Parse Javadoc content and extract the description, @param, and @return
|
|
63
|
+
*/
|
|
64
|
+
function parseJavadocContent(javadoc) {
|
|
65
|
+
// Remove /** and */
|
|
66
|
+
let content = javadoc.replace(/^\/\*\*/, '').replace(/\*\/$/, '');
|
|
67
|
+
// Split into lines and process each line
|
|
68
|
+
const lines = content.split('\n').map((line) => {
|
|
69
|
+
// Remove leading whitespace and asterisks
|
|
70
|
+
return line.replace(/^\s*\*?\s?/, '');
|
|
71
|
+
});
|
|
72
|
+
const descriptionLines = [];
|
|
73
|
+
const params = {};
|
|
74
|
+
let returns;
|
|
75
|
+
let currentTag = null;
|
|
76
|
+
let currentParamName = null;
|
|
77
|
+
let currentTagContent = [];
|
|
78
|
+
const flushCurrentTag = () => {
|
|
79
|
+
if (currentTag === 'param' && currentParamName) {
|
|
80
|
+
params[currentParamName] = currentTagContent.join(' ').trim();
|
|
81
|
+
}
|
|
82
|
+
else if (currentTag === 'return' || currentTag === 'returns') {
|
|
83
|
+
returns = currentTagContent.join(' ').trim();
|
|
84
|
+
}
|
|
85
|
+
currentTag = null;
|
|
86
|
+
currentParamName = null;
|
|
87
|
+
currentTagContent = [];
|
|
88
|
+
};
|
|
89
|
+
for (const line of lines) {
|
|
90
|
+
if (line.startsWith('@param ')) {
|
|
91
|
+
flushCurrentTag();
|
|
92
|
+
currentTag = 'param';
|
|
93
|
+
// Extract param name and description
|
|
94
|
+
const paramMatch = line.match(/^@param\s+(\w+)\s*(.*)/);
|
|
95
|
+
if (paramMatch) {
|
|
96
|
+
currentParamName = paramMatch[1];
|
|
97
|
+
if (paramMatch[2]) {
|
|
98
|
+
currentTagContent.push(paramMatch[2]);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (line.startsWith('@return ') || line.startsWith('@returns ')) {
|
|
103
|
+
flushCurrentTag();
|
|
104
|
+
currentTag = 'return';
|
|
105
|
+
const returnMatch = line.match(/^@returns?\s+(.*)/);
|
|
106
|
+
if (returnMatch && returnMatch[1]) {
|
|
107
|
+
currentTagContent.push(returnMatch[1]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (line.startsWith('@')) {
|
|
111
|
+
// Other tags like @throws, @see, etc. - flush current and ignore
|
|
112
|
+
flushCurrentTag();
|
|
113
|
+
}
|
|
114
|
+
else if (currentTag) {
|
|
115
|
+
// Continuation of current tag
|
|
116
|
+
currentTagContent.push(line);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Description line
|
|
120
|
+
descriptionLines.push(line);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Flush any remaining tag
|
|
124
|
+
flushCurrentTag();
|
|
125
|
+
return {
|
|
126
|
+
description: descriptionLines.join('\n').trim(),
|
|
127
|
+
info: {
|
|
128
|
+
description: descriptionLines.join('\n').trim() || undefined,
|
|
129
|
+
params,
|
|
130
|
+
returns,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
class JavaFileParser {
|
|
135
|
+
sourceDir;
|
|
136
|
+
constructor(sourceDir) {
|
|
137
|
+
this.sourceDir = sourceDir;
|
|
138
|
+
}
|
|
139
|
+
async parseAllJavaFiles() {
|
|
140
|
+
const javaClasses = new Map();
|
|
141
|
+
const javaFiles = this.findJavaFiles(this.sourceDir);
|
|
142
|
+
for (const filePath of javaFiles) {
|
|
143
|
+
try {
|
|
144
|
+
const classes = await this.parseJavaFile(filePath);
|
|
145
|
+
for (const javaClass of classes) {
|
|
146
|
+
javaClasses.set(javaClass.name, javaClass);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error(`Error parsing ${filePath}:`, error instanceof Error ? error.message : error);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return javaClasses;
|
|
154
|
+
}
|
|
155
|
+
findJavaFiles(dir) {
|
|
156
|
+
const files = [];
|
|
157
|
+
if (!fs.existsSync(dir)) {
|
|
158
|
+
return files;
|
|
159
|
+
}
|
|
160
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
161
|
+
for (const entry of entries) {
|
|
162
|
+
const fullPath = path.join(dir, entry.name);
|
|
163
|
+
if (entry.isDirectory()) {
|
|
164
|
+
files.push(...this.findJavaFiles(fullPath));
|
|
165
|
+
}
|
|
166
|
+
else if (entry.isFile() && entry.name.endsWith('.java')) {
|
|
167
|
+
files.push(fullPath);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return files;
|
|
171
|
+
}
|
|
172
|
+
async parseJavaFile(filePath) {
|
|
173
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
174
|
+
try {
|
|
175
|
+
const cst = (0, java_parser_1.parse)(content);
|
|
176
|
+
const javadocs = extractJavadocs(content);
|
|
177
|
+
const extractor = new JavaClassExtractor(filePath, content, javadocs);
|
|
178
|
+
extractor.visit(cst);
|
|
179
|
+
return extractor.getAllClasses();
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
console.error(`Failed to parse ${filePath}:`, error instanceof Error ? error.message : error);
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.JavaFileParser = JavaFileParser;
|
|
188
|
+
class JavaClassExtractor extends java_parser_1.BaseJavaCstVisitorWithDefaults {
|
|
189
|
+
filePath;
|
|
190
|
+
sourceContent;
|
|
191
|
+
javadocs;
|
|
192
|
+
_packageName = '';
|
|
193
|
+
currentAnnotations = [];
|
|
194
|
+
// Stack for handling nested classes
|
|
195
|
+
classStack = [];
|
|
196
|
+
allClasses = [];
|
|
197
|
+
constructor(filePath, sourceContent, javadocs) {
|
|
198
|
+
super();
|
|
199
|
+
this.filePath = filePath;
|
|
200
|
+
this.sourceContent = sourceContent;
|
|
201
|
+
this.javadocs = javadocs;
|
|
202
|
+
this.validateVisitor();
|
|
203
|
+
}
|
|
204
|
+
get currentClass() {
|
|
205
|
+
return this.classStack[this.classStack.length - 1];
|
|
206
|
+
}
|
|
207
|
+
getJavaClass() {
|
|
208
|
+
// Return the first (top-level) class for backward compatibility
|
|
209
|
+
return this.allClasses.length > 0 ? this.allClasses[0] : null;
|
|
210
|
+
}
|
|
211
|
+
getAllClasses() {
|
|
212
|
+
return this.allClasses;
|
|
213
|
+
}
|
|
214
|
+
finalizeClass(ctx) {
|
|
215
|
+
this.allClasses.push({
|
|
216
|
+
name: ctx.className,
|
|
217
|
+
packageName: this._packageName,
|
|
218
|
+
annotations: ctx.classAnnotations,
|
|
219
|
+
methods: ctx.methods,
|
|
220
|
+
fields: ctx.fields,
|
|
221
|
+
filePath: this.filePath,
|
|
222
|
+
javadoc: ctx.classJavadoc,
|
|
223
|
+
superClass: ctx.superClassName,
|
|
224
|
+
isEnum: ctx.isEnum,
|
|
225
|
+
enumValues: ctx.isEnum ? ctx.enumValues : undefined,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
packageDeclaration(ctx) {
|
|
229
|
+
if (ctx.Identifier) {
|
|
230
|
+
this._packageName = ctx.Identifier.map((id) => id.image).join('.');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
normalClassDeclaration(ctx) {
|
|
234
|
+
// Create a new class context
|
|
235
|
+
const classContext = {
|
|
236
|
+
className: '',
|
|
237
|
+
classAnnotations: [...this.currentAnnotations],
|
|
238
|
+
methods: [],
|
|
239
|
+
fields: [],
|
|
240
|
+
isEnum: false,
|
|
241
|
+
enumValues: [],
|
|
242
|
+
};
|
|
243
|
+
this.currentAnnotations = [];
|
|
244
|
+
// Extract class name
|
|
245
|
+
if (ctx.typeIdentifier?.[0]?.children?.Identifier?.[0]) {
|
|
246
|
+
classContext.className = ctx.typeIdentifier[0].children.Identifier[0].image;
|
|
247
|
+
// Find javadoc for this class
|
|
248
|
+
const classToken = ctx.typeIdentifier[0].children.Identifier[0];
|
|
249
|
+
if (classToken.startLine) {
|
|
250
|
+
const parsedJavadoc = this.findJavadocForLine(classToken.startLine);
|
|
251
|
+
classContext.classJavadoc = parsedJavadoc?.description;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Extract superclass name from classExtends
|
|
255
|
+
if (ctx.classExtends?.[0]) {
|
|
256
|
+
const classExtendsChildren = ctx.classExtends[0].children || ctx.classExtends[0];
|
|
257
|
+
if (classExtendsChildren.classType?.[0]) {
|
|
258
|
+
const classTypeChildren = classExtendsChildren.classType[0].children || classExtendsChildren.classType[0];
|
|
259
|
+
if (classTypeChildren.Identifier) {
|
|
260
|
+
// Join all identifiers for fully qualified names
|
|
261
|
+
classContext.superClassName = classTypeChildren.Identifier.map((id) => id.image).join('.');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Push to stack and visit class body
|
|
266
|
+
this.classStack.push(classContext);
|
|
267
|
+
if (ctx.classBody) {
|
|
268
|
+
this.visit(ctx.classBody);
|
|
269
|
+
}
|
|
270
|
+
// Pop from stack and finalize the class
|
|
271
|
+
const completed = this.classStack.pop();
|
|
272
|
+
if (completed && completed.className) {
|
|
273
|
+
this.finalizeClass(completed);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
enumDeclaration(ctx) {
|
|
277
|
+
// Create a new enum context
|
|
278
|
+
const enumContext = {
|
|
279
|
+
className: '',
|
|
280
|
+
classAnnotations: [...this.currentAnnotations],
|
|
281
|
+
methods: [],
|
|
282
|
+
fields: [],
|
|
283
|
+
isEnum: true,
|
|
284
|
+
enumValues: [],
|
|
285
|
+
};
|
|
286
|
+
this.currentAnnotations = [];
|
|
287
|
+
// Get enum name
|
|
288
|
+
if (ctx.typeIdentifier?.[0]?.children?.Identifier?.[0]) {
|
|
289
|
+
enumContext.className = ctx.typeIdentifier[0].children.Identifier[0].image;
|
|
290
|
+
// Find javadoc for this enum
|
|
291
|
+
const enumToken = ctx.typeIdentifier[0].children.Identifier[0];
|
|
292
|
+
if (enumToken.startLine) {
|
|
293
|
+
const parsedJavadoc = this.findJavadocForLine(enumToken.startLine);
|
|
294
|
+
enumContext.classJavadoc = parsedJavadoc?.description;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Extract enum constants
|
|
298
|
+
if (ctx.enumBody?.[0]) {
|
|
299
|
+
const enumBodyChildren = ctx.enumBody[0].children || ctx.enumBody[0];
|
|
300
|
+
if (enumBodyChildren.enumConstantList?.[0]) {
|
|
301
|
+
const constantListChildren = enumBodyChildren.enumConstantList[0].children || enumBodyChildren.enumConstantList[0];
|
|
302
|
+
if (constantListChildren.enumConstant) {
|
|
303
|
+
for (const enumConstant of constantListChildren.enumConstant) {
|
|
304
|
+
const constantChildren = enumConstant.children || enumConstant;
|
|
305
|
+
if (constantChildren.Identifier?.[0]) {
|
|
306
|
+
enumContext.enumValues.push(constantChildren.Identifier[0].image);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Finalize the enum (enums don't have a body to visit for nested classes)
|
|
313
|
+
if (enumContext.className) {
|
|
314
|
+
this.finalizeClass(enumContext);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Find javadoc that ends near the given line (within a few lines before)
|
|
319
|
+
*/
|
|
320
|
+
findJavadocForLine(targetLine) {
|
|
321
|
+
// Look for javadoc that ends 1-10 lines before the target line
|
|
322
|
+
// (allowing for annotations between javadoc and declaration)
|
|
323
|
+
for (let offset = 1; offset <= 10; offset++) {
|
|
324
|
+
const javadoc = this.javadocs.get(targetLine - offset);
|
|
325
|
+
if (javadoc) {
|
|
326
|
+
return javadoc;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return undefined;
|
|
330
|
+
}
|
|
331
|
+
classModifier(ctx) {
|
|
332
|
+
if (ctx.annotation) {
|
|
333
|
+
for (const annotationCtx of ctx.annotation) {
|
|
334
|
+
const annotation = this.extractAnnotation(annotationCtx);
|
|
335
|
+
if (annotation) {
|
|
336
|
+
this.currentAnnotations.push(annotation);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
methodDeclaration(ctx) {
|
|
342
|
+
// Extract annotations directly from methodModifier nodes
|
|
343
|
+
const methodAnnotations = [];
|
|
344
|
+
let methodStartLine;
|
|
345
|
+
if (ctx.methodModifier) {
|
|
346
|
+
for (const modifierCtx of ctx.methodModifier) {
|
|
347
|
+
const modChildren = modifierCtx.children || modifierCtx;
|
|
348
|
+
if (modChildren.annotation) {
|
|
349
|
+
for (const annotationCtx of modChildren.annotation) {
|
|
350
|
+
const annotation = this.extractAnnotation(annotationCtx);
|
|
351
|
+
if (annotation) {
|
|
352
|
+
methodAnnotations.push(annotation);
|
|
353
|
+
}
|
|
354
|
+
// Track the earliest line of the method declaration
|
|
355
|
+
const annChildren = annotationCtx.children || annotationCtx;
|
|
356
|
+
if (annChildren.At?.[0]?.startLine && (!methodStartLine || annChildren.At[0].startLine < methodStartLine)) {
|
|
357
|
+
methodStartLine = annChildren.At[0].startLine;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
const methodHeader = ctx.methodHeader?.[0];
|
|
364
|
+
if (!methodHeader)
|
|
365
|
+
return;
|
|
366
|
+
const methodName = this.extractMethodName(methodHeader);
|
|
367
|
+
const returnType = this.extractReturnType(methodHeader);
|
|
368
|
+
const parameters = this.extractParameters(methodHeader);
|
|
369
|
+
// Find javadoc for this method
|
|
370
|
+
let methodJavadoc;
|
|
371
|
+
let methodJavadocInfo;
|
|
372
|
+
if (methodStartLine) {
|
|
373
|
+
const parsedJavadoc = this.findJavadocForLine(methodStartLine);
|
|
374
|
+
methodJavadoc = parsedJavadoc?.description;
|
|
375
|
+
methodJavadocInfo = parsedJavadoc?.info;
|
|
376
|
+
}
|
|
377
|
+
if (methodName && this.currentClass) {
|
|
378
|
+
this.currentClass.methods.push({
|
|
379
|
+
name: methodName,
|
|
380
|
+
returnType: returnType.type,
|
|
381
|
+
returnGenericType: returnType.genericType,
|
|
382
|
+
parameters,
|
|
383
|
+
annotations: methodAnnotations,
|
|
384
|
+
javadoc: methodJavadoc,
|
|
385
|
+
javadocInfo: methodJavadocInfo,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
fieldDeclaration(ctx) {
|
|
390
|
+
// Extract annotations and check for static modifier from fieldModifier nodes
|
|
391
|
+
const fieldAnnotations = [];
|
|
392
|
+
let isStatic = false;
|
|
393
|
+
let fieldStartLine;
|
|
394
|
+
if (ctx.fieldModifier) {
|
|
395
|
+
for (const modifier of ctx.fieldModifier) {
|
|
396
|
+
const modChildren = modifier.children || modifier;
|
|
397
|
+
// Check for static modifier
|
|
398
|
+
if (modChildren.Static) {
|
|
399
|
+
isStatic = true;
|
|
400
|
+
}
|
|
401
|
+
// Extract annotations and track start line
|
|
402
|
+
if (modChildren.annotation) {
|
|
403
|
+
for (const annotationCtx of modChildren.annotation) {
|
|
404
|
+
const annotation = this.extractAnnotation(annotationCtx);
|
|
405
|
+
if (annotation) {
|
|
406
|
+
fieldAnnotations.push(annotation);
|
|
407
|
+
}
|
|
408
|
+
// Track the earliest line of the field declaration
|
|
409
|
+
const annChildren = annotationCtx.children || annotationCtx;
|
|
410
|
+
if (annChildren.At?.[0]?.startLine && (!fieldStartLine || annChildren.At[0].startLine < fieldStartLine)) {
|
|
411
|
+
fieldStartLine = annChildren.At[0].startLine;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
// Skip static fields
|
|
418
|
+
if (isStatic)
|
|
419
|
+
return;
|
|
420
|
+
const unannType = ctx.unannType?.[0];
|
|
421
|
+
const variableDeclaratorList = ctx.variableDeclaratorList?.[0];
|
|
422
|
+
if (!unannType || !variableDeclaratorList)
|
|
423
|
+
return;
|
|
424
|
+
// If no annotation found, try to get start line from type
|
|
425
|
+
if (!fieldStartLine && unannType) {
|
|
426
|
+
fieldStartLine = this.getStartLineFromNode(unannType);
|
|
427
|
+
}
|
|
428
|
+
const typeInfo = this.extractType(unannType);
|
|
429
|
+
const fieldNames = this.extractFieldNames(variableDeclaratorList);
|
|
430
|
+
// Find javadoc for this field
|
|
431
|
+
let fieldJavadoc;
|
|
432
|
+
if (fieldStartLine) {
|
|
433
|
+
const parsedJavadoc = this.findJavadocForLine(fieldStartLine);
|
|
434
|
+
fieldJavadoc = parsedJavadoc?.description;
|
|
435
|
+
}
|
|
436
|
+
if (this.currentClass) {
|
|
437
|
+
for (const fieldName of fieldNames) {
|
|
438
|
+
this.currentClass.fields.push({
|
|
439
|
+
name: fieldName,
|
|
440
|
+
type: typeInfo.type,
|
|
441
|
+
genericType: typeInfo.genericType,
|
|
442
|
+
annotations: fieldAnnotations,
|
|
443
|
+
accessModifier: 'private', // Default, could be extracted from modifiers
|
|
444
|
+
javadoc: fieldJavadoc,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Get the start line from a CST node by recursively searching for tokens
|
|
451
|
+
*/
|
|
452
|
+
getStartLineFromNode(node) {
|
|
453
|
+
if (!node)
|
|
454
|
+
return undefined;
|
|
455
|
+
const children = node.children || node;
|
|
456
|
+
// Check if this is a token with startLine
|
|
457
|
+
if (children.startLine) {
|
|
458
|
+
return children.startLine;
|
|
459
|
+
}
|
|
460
|
+
// Recursively search children
|
|
461
|
+
for (const key of Object.keys(children)) {
|
|
462
|
+
const child = children[key];
|
|
463
|
+
if (Array.isArray(child)) {
|
|
464
|
+
for (const item of child) {
|
|
465
|
+
if (item?.startLine) {
|
|
466
|
+
return item.startLine;
|
|
467
|
+
}
|
|
468
|
+
const result = this.getStartLineFromNode(item);
|
|
469
|
+
if (result)
|
|
470
|
+
return result;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
else if (child?.startLine) {
|
|
474
|
+
return child.startLine;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return undefined;
|
|
478
|
+
}
|
|
479
|
+
extractAnnotation(ctx) {
|
|
480
|
+
const children = ctx.children || ctx;
|
|
481
|
+
// Get annotation name
|
|
482
|
+
let name = '';
|
|
483
|
+
if (children.typeName?.[0]) {
|
|
484
|
+
name = this.extractTypeName(children.typeName[0]);
|
|
485
|
+
}
|
|
486
|
+
else if (children.Identifier) {
|
|
487
|
+
name = children.Identifier.map((id) => id.image).join('.');
|
|
488
|
+
}
|
|
489
|
+
if (!name)
|
|
490
|
+
return null;
|
|
491
|
+
// Remove @ prefix if present
|
|
492
|
+
name = name.replace(/^@/, '');
|
|
493
|
+
// Extract annotation values
|
|
494
|
+
const values = {};
|
|
495
|
+
if (children.elementValuePairList?.[0]) {
|
|
496
|
+
this.extractElementValuePairs(children.elementValuePairList[0], values);
|
|
497
|
+
}
|
|
498
|
+
else if (children.elementValue?.[0]) {
|
|
499
|
+
// Single value annotation like @GetMapping("/path")
|
|
500
|
+
values['value'] = this.extractElementValue(children.elementValue[0]);
|
|
501
|
+
}
|
|
502
|
+
return { name, values };
|
|
503
|
+
}
|
|
504
|
+
extractElementValuePairs(ctx, values) {
|
|
505
|
+
const children = ctx.children || ctx;
|
|
506
|
+
const pairs = children.elementValuePair || [];
|
|
507
|
+
for (const pair of pairs) {
|
|
508
|
+
const pairChildren = pair.children || pair;
|
|
509
|
+
const key = pairChildren.Identifier?.[0]?.image || 'value';
|
|
510
|
+
const value = this.extractElementValue(pairChildren.elementValue?.[0]);
|
|
511
|
+
values[key] = value;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
extractElementValue(ctx) {
|
|
515
|
+
if (!ctx)
|
|
516
|
+
return '';
|
|
517
|
+
const children = ctx.children || ctx;
|
|
518
|
+
// Array initializer
|
|
519
|
+
if (children.elementValueArrayInitializer?.[0]) {
|
|
520
|
+
const arrayInit = children.elementValueArrayInitializer[0];
|
|
521
|
+
const arrayChildren = arrayInit.children || arrayInit;
|
|
522
|
+
const elementValues = arrayChildren.elementValue || [];
|
|
523
|
+
return elementValues.map((ev) => this.extractElementValue(ev)).flat();
|
|
524
|
+
}
|
|
525
|
+
// Conditional expression (includes literals and identifiers)
|
|
526
|
+
if (children.conditionalExpression?.[0]) {
|
|
527
|
+
return this.extractExpressionValue(children.conditionalExpression[0]);
|
|
528
|
+
}
|
|
529
|
+
// Annotation
|
|
530
|
+
if (children.annotation?.[0]) {
|
|
531
|
+
return this.extractAnnotationAsString(children.annotation[0]);
|
|
532
|
+
}
|
|
533
|
+
return '';
|
|
534
|
+
}
|
|
535
|
+
extractExpressionValue(ctx) {
|
|
536
|
+
const children = ctx.children || ctx;
|
|
537
|
+
// Handle string literals
|
|
538
|
+
if (children.StringLiteral?.[0]) {
|
|
539
|
+
return children.StringLiteral[0].image.replace(/^"|"$/g, '');
|
|
540
|
+
}
|
|
541
|
+
// Handle boolean literals
|
|
542
|
+
if (children.True?.[0])
|
|
543
|
+
return 'true';
|
|
544
|
+
if (children.False?.[0])
|
|
545
|
+
return 'false';
|
|
546
|
+
// Handle numeric literals
|
|
547
|
+
if (children.IntegerLiteral?.[0])
|
|
548
|
+
return children.IntegerLiteral[0].image;
|
|
549
|
+
if (children.FloatingPointLiteral?.[0])
|
|
550
|
+
return children.FloatingPointLiteral[0].image;
|
|
551
|
+
// Handle identifiers (enum values, etc.)
|
|
552
|
+
if (children.Identifier?.[0])
|
|
553
|
+
return children.Identifier[0].image;
|
|
554
|
+
// Recursively search for values in nested structures
|
|
555
|
+
for (const key of Object.keys(children)) {
|
|
556
|
+
if (Array.isArray(children[key]) && children[key].length > 0) {
|
|
557
|
+
const result = this.extractExpressionValue(children[key][0]);
|
|
558
|
+
if (result)
|
|
559
|
+
return result;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return '';
|
|
563
|
+
}
|
|
564
|
+
extractAnnotationAsString(ctx) {
|
|
565
|
+
const children = ctx.children || ctx;
|
|
566
|
+
let name = '';
|
|
567
|
+
if (children.typeName?.[0]) {
|
|
568
|
+
name = this.extractTypeName(children.typeName[0]);
|
|
569
|
+
}
|
|
570
|
+
return `@${name}`;
|
|
571
|
+
}
|
|
572
|
+
extractTypeName(ctx) {
|
|
573
|
+
const children = ctx.children || ctx;
|
|
574
|
+
if (children.Identifier) {
|
|
575
|
+
return children.Identifier.map((id) => id.image).join('.');
|
|
576
|
+
}
|
|
577
|
+
return '';
|
|
578
|
+
}
|
|
579
|
+
extractMethodName(methodHeader) {
|
|
580
|
+
const children = methodHeader.children || methodHeader;
|
|
581
|
+
const declarator = children.methodDeclarator?.[0];
|
|
582
|
+
if (declarator) {
|
|
583
|
+
const declChildren = declarator.children || declarator;
|
|
584
|
+
return declChildren.Identifier?.[0]?.image || '';
|
|
585
|
+
}
|
|
586
|
+
return '';
|
|
587
|
+
}
|
|
588
|
+
extractReturnType(methodHeader) {
|
|
589
|
+
const children = methodHeader.children || methodHeader;
|
|
590
|
+
const result = children.result?.[0];
|
|
591
|
+
if (!result)
|
|
592
|
+
return { type: 'void' };
|
|
593
|
+
const resultChildren = result.children || result;
|
|
594
|
+
if (resultChildren.Void) {
|
|
595
|
+
return { type: 'void' };
|
|
596
|
+
}
|
|
597
|
+
if (resultChildren.unannType?.[0]) {
|
|
598
|
+
return this.extractType(resultChildren.unannType[0]);
|
|
599
|
+
}
|
|
600
|
+
return { type: 'Object' };
|
|
601
|
+
}
|
|
602
|
+
extractType(typeCtx) {
|
|
603
|
+
const children = typeCtx.children || typeCtx;
|
|
604
|
+
// Handle primitive types with optional dims suffix (e.g., boolean, int, etc.)
|
|
605
|
+
if (children.unannPrimitiveTypeWithOptionalDimsSuffix?.[0]) {
|
|
606
|
+
const primitiveWithDims = children.unannPrimitiveTypeWithOptionalDimsSuffix[0].children || children.unannPrimitiveTypeWithOptionalDimsSuffix[0];
|
|
607
|
+
if (primitiveWithDims.unannPrimitiveType?.[0]) {
|
|
608
|
+
const primitiveChildren = primitiveWithDims.unannPrimitiveType[0].children || primitiveWithDims.unannPrimitiveType[0];
|
|
609
|
+
return this.extractPrimitiveType(primitiveChildren);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
// Handle primitive types directly (fallback for older parser versions)
|
|
613
|
+
if (children.unannPrimitiveType?.[0]) {
|
|
614
|
+
const primitiveChildren = children.unannPrimitiveType[0].children || children.unannPrimitiveType[0];
|
|
615
|
+
return this.extractPrimitiveType(primitiveChildren);
|
|
616
|
+
}
|
|
617
|
+
// Handle reference types
|
|
618
|
+
if (children.unannReferenceType?.[0]) {
|
|
619
|
+
return this.extractReferenceType(children.unannReferenceType[0]);
|
|
620
|
+
}
|
|
621
|
+
return { type: 'Object' };
|
|
622
|
+
}
|
|
623
|
+
extractPrimitiveType(primitiveChildren) {
|
|
624
|
+
if (primitiveChildren.numericType?.[0]) {
|
|
625
|
+
const numericChildren = primitiveChildren.numericType[0].children || primitiveChildren.numericType[0];
|
|
626
|
+
if (numericChildren.integralType?.[0]) {
|
|
627
|
+
const integralChildren = numericChildren.integralType[0].children || numericChildren.integralType[0];
|
|
628
|
+
for (const key of ['Int', 'Long', 'Short', 'Byte', 'Char']) {
|
|
629
|
+
if (integralChildren[key])
|
|
630
|
+
return { type: key.toLowerCase() };
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (numericChildren.floatingPointType?.[0]) {
|
|
634
|
+
const floatChildren = numericChildren.floatingPointType[0].children || numericChildren.floatingPointType[0];
|
|
635
|
+
if (floatChildren.Float)
|
|
636
|
+
return { type: 'float' };
|
|
637
|
+
if (floatChildren.Double)
|
|
638
|
+
return { type: 'double' };
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
if (primitiveChildren.Boolean)
|
|
642
|
+
return { type: 'boolean' };
|
|
643
|
+
return { type: 'Object' };
|
|
644
|
+
}
|
|
645
|
+
extractReferenceType(refTypeCtx) {
|
|
646
|
+
const children = refTypeCtx.children || refTypeCtx;
|
|
647
|
+
// Handle class or interface type
|
|
648
|
+
if (children.unannClassOrInterfaceType?.[0]) {
|
|
649
|
+
return this.extractClassOrInterfaceType(children.unannClassOrInterfaceType[0]);
|
|
650
|
+
}
|
|
651
|
+
// Handle array type
|
|
652
|
+
if (children.unannArrayType?.[0]) {
|
|
653
|
+
const arrayChildren = children.unannArrayType[0].children || children.unannArrayType[0];
|
|
654
|
+
if (arrayChildren.unannClassOrInterfaceType?.[0]) {
|
|
655
|
+
const innerType = this.extractClassOrInterfaceType(arrayChildren.unannClassOrInterfaceType[0]);
|
|
656
|
+
return { type: `${innerType.type}[]`, genericType: innerType.genericType };
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
return { type: 'Object' };
|
|
660
|
+
}
|
|
661
|
+
extractClassOrInterfaceType(ctx) {
|
|
662
|
+
const children = ctx.children || ctx;
|
|
663
|
+
let type = '';
|
|
664
|
+
let genericType;
|
|
665
|
+
// Handle the class type
|
|
666
|
+
if (children.unannClassType?.[0]) {
|
|
667
|
+
const classTypeChildren = children.unannClassType[0].children || children.unannClassType[0];
|
|
668
|
+
// Get the class name from annotation chain or directly
|
|
669
|
+
if (classTypeChildren.Identifier) {
|
|
670
|
+
type = classTypeChildren.Identifier.map((id) => id.image).join('.');
|
|
671
|
+
}
|
|
672
|
+
// Check for generic type arguments
|
|
673
|
+
if (classTypeChildren.typeArguments?.[0]) {
|
|
674
|
+
genericType = this.extractTypeArguments(classTypeChildren.typeArguments[0]);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
return { type: type || 'Object', genericType };
|
|
678
|
+
}
|
|
679
|
+
extractTypeArguments(ctx) {
|
|
680
|
+
const children = ctx.children || ctx;
|
|
681
|
+
const typeArgumentList = children.typeArgumentList?.[0];
|
|
682
|
+
if (!typeArgumentList)
|
|
683
|
+
return '';
|
|
684
|
+
const typeArgChildren = typeArgumentList.children || typeArgumentList;
|
|
685
|
+
const typeArguments = typeArgChildren.typeArgument || [];
|
|
686
|
+
const types = typeArguments.map((arg) => {
|
|
687
|
+
const argChildren = arg.children || arg;
|
|
688
|
+
if (argChildren.referenceType?.[0]) {
|
|
689
|
+
const refType = this.extractReferenceTypeFromGeneric(argChildren.referenceType[0]);
|
|
690
|
+
return refType;
|
|
691
|
+
}
|
|
692
|
+
if (argChildren.wildcard?.[0]) {
|
|
693
|
+
return '?';
|
|
694
|
+
}
|
|
695
|
+
return 'Object';
|
|
696
|
+
});
|
|
697
|
+
return types.join(', ');
|
|
698
|
+
}
|
|
699
|
+
extractReferenceTypeFromGeneric(refTypeCtx) {
|
|
700
|
+
const children = refTypeCtx.children || refTypeCtx;
|
|
701
|
+
if (children.classOrInterfaceType?.[0]) {
|
|
702
|
+
const classTypeChildren = children.classOrInterfaceType[0].children || children.classOrInterfaceType[0];
|
|
703
|
+
if (classTypeChildren.classType?.[0]) {
|
|
704
|
+
const innerClassChildren = classTypeChildren.classType[0].children || classTypeChildren.classType[0];
|
|
705
|
+
if (innerClassChildren.Identifier) {
|
|
706
|
+
let typeName = innerClassChildren.Identifier.map((id) => id.image).join('.');
|
|
707
|
+
// Handle nested generic types
|
|
708
|
+
if (innerClassChildren.typeArguments?.[0]) {
|
|
709
|
+
const nestedGenerics = this.extractTypeArguments(innerClassChildren.typeArguments[0]);
|
|
710
|
+
if (nestedGenerics) {
|
|
711
|
+
typeName += `<${nestedGenerics}>`;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
return typeName;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return 'Object';
|
|
719
|
+
}
|
|
720
|
+
extractParameters(methodHeader) {
|
|
721
|
+
const children = methodHeader.children || methodHeader;
|
|
722
|
+
const declarator = children.methodDeclarator?.[0];
|
|
723
|
+
if (!declarator)
|
|
724
|
+
return [];
|
|
725
|
+
const declChildren = declarator.children || declarator;
|
|
726
|
+
const formalParameterList = declChildren.formalParameterList?.[0];
|
|
727
|
+
if (!formalParameterList)
|
|
728
|
+
return [];
|
|
729
|
+
const formalChildren = formalParameterList.children || formalParameterList;
|
|
730
|
+
const parameters = [];
|
|
731
|
+
// Handle regular formal parameters
|
|
732
|
+
if (formalChildren.formalParameter) {
|
|
733
|
+
for (const param of formalChildren.formalParameter) {
|
|
734
|
+
const parameter = this.extractFormalParameter(param);
|
|
735
|
+
if (parameter) {
|
|
736
|
+
parameters.push(parameter);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return parameters;
|
|
741
|
+
}
|
|
742
|
+
extractFormalParameter(paramCtx) {
|
|
743
|
+
let children = paramCtx.children || paramCtx;
|
|
744
|
+
// Handle variableParaRegularParameter wrapper
|
|
745
|
+
if (children.variableParaRegularParameter?.[0]) {
|
|
746
|
+
children = children.variableParaRegularParameter[0].children || children.variableParaRegularParameter[0];
|
|
747
|
+
}
|
|
748
|
+
// Extract annotations from variableModifier
|
|
749
|
+
const annotations = [];
|
|
750
|
+
if (children.variableModifier) {
|
|
751
|
+
for (const modifier of children.variableModifier) {
|
|
752
|
+
const modChildren = modifier.children || modifier;
|
|
753
|
+
if (modChildren.annotation?.[0]) {
|
|
754
|
+
const annotation = this.extractAnnotation(modChildren.annotation[0]);
|
|
755
|
+
if (annotation) {
|
|
756
|
+
annotations.push(annotation);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
// Extract type
|
|
762
|
+
let type = 'Object';
|
|
763
|
+
let genericType;
|
|
764
|
+
if (children.unannType?.[0]) {
|
|
765
|
+
const typeInfo = this.extractType(children.unannType[0]);
|
|
766
|
+
type = typeInfo.type;
|
|
767
|
+
genericType = typeInfo.genericType;
|
|
768
|
+
}
|
|
769
|
+
// Extract parameter name
|
|
770
|
+
let name = '';
|
|
771
|
+
if (children.variableDeclaratorId?.[0]) {
|
|
772
|
+
const varIdChildren = children.variableDeclaratorId[0].children || children.variableDeclaratorId[0];
|
|
773
|
+
name = varIdChildren.Identifier?.[0]?.image || '';
|
|
774
|
+
}
|
|
775
|
+
if (!name)
|
|
776
|
+
return null;
|
|
777
|
+
return {
|
|
778
|
+
name,
|
|
779
|
+
type,
|
|
780
|
+
genericType,
|
|
781
|
+
annotations,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
extractFieldNames(variableDeclaratorList) {
|
|
785
|
+
const children = variableDeclaratorList.children || variableDeclaratorList;
|
|
786
|
+
const declarators = children.variableDeclarator || [];
|
|
787
|
+
const names = [];
|
|
788
|
+
for (const declarator of declarators) {
|
|
789
|
+
const declChildren = declarator.children || declarator;
|
|
790
|
+
if (declChildren.variableDeclaratorId?.[0]) {
|
|
791
|
+
const varIdChildren = declChildren.variableDeclaratorId[0].children || declChildren.variableDeclaratorId[0];
|
|
792
|
+
const name = varIdChildren.Identifier?.[0]?.image;
|
|
793
|
+
if (name) {
|
|
794
|
+
names.push(name);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return names;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
function parseJavaSource(sourceDir) {
|
|
802
|
+
const parser = new JavaFileParser(sourceDir);
|
|
803
|
+
return parser.parseAllJavaFiles();
|
|
804
|
+
}
|
|
805
|
+
//# sourceMappingURL=javaParser.js.map
|