tree-sitter-analyzer 0.4.0__py3-none-any.whl → 0.6.1__py3-none-any.whl

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.

Potentially problematic release.


This version of tree-sitter-analyzer might be problematic. Click here for more details.

Files changed (38) hide show
  1. tree_sitter_analyzer/__init__.py +1 -3
  2. tree_sitter_analyzer/__main__.py +2 -2
  3. tree_sitter_analyzer/cli/commands/default_command.py +1 -1
  4. tree_sitter_analyzer/cli/commands/query_command.py +5 -5
  5. tree_sitter_analyzer/cli/commands/table_command.py +3 -3
  6. tree_sitter_analyzer/cli/info_commands.py +14 -13
  7. tree_sitter_analyzer/cli_main.py +49 -30
  8. tree_sitter_analyzer/core/analysis_engine.py +21 -21
  9. tree_sitter_analyzer/core/cache_service.py +31 -31
  10. tree_sitter_analyzer/core/query.py +502 -502
  11. tree_sitter_analyzer/encoding_utils.py +5 -2
  12. tree_sitter_analyzer/file_handler.py +3 -3
  13. tree_sitter_analyzer/formatters/base_formatter.py +18 -18
  14. tree_sitter_analyzer/formatters/formatter_factory.py +15 -15
  15. tree_sitter_analyzer/formatters/java_formatter.py +291 -291
  16. tree_sitter_analyzer/formatters/python_formatter.py +259 -259
  17. tree_sitter_analyzer/interfaces/cli_adapter.py +32 -32
  18. tree_sitter_analyzer/interfaces/mcp_adapter.py +2 -2
  19. tree_sitter_analyzer/language_detector.py +398 -398
  20. tree_sitter_analyzer/language_loader.py +224 -224
  21. tree_sitter_analyzer/languages/java_plugin.py +1174 -1174
  22. tree_sitter_analyzer/languages/python_plugin.py +10 -2
  23. tree_sitter_analyzer/mcp/resources/project_stats_resource.py +555 -555
  24. tree_sitter_analyzer/models.py +470 -470
  25. tree_sitter_analyzer/output_manager.py +8 -10
  26. tree_sitter_analyzer/plugins/base.py +33 -0
  27. tree_sitter_analyzer/queries/java.py +78 -78
  28. tree_sitter_analyzer/queries/javascript.py +7 -7
  29. tree_sitter_analyzer/queries/python.py +18 -18
  30. tree_sitter_analyzer/queries/typescript.py +12 -12
  31. tree_sitter_analyzer/query_loader.py +13 -13
  32. tree_sitter_analyzer/table_formatter.py +20 -18
  33. tree_sitter_analyzer/utils.py +1 -1
  34. {tree_sitter_analyzer-0.4.0.dist-info → tree_sitter_analyzer-0.6.1.dist-info}/METADATA +10 -10
  35. {tree_sitter_analyzer-0.4.0.dist-info → tree_sitter_analyzer-0.6.1.dist-info}/RECORD +37 -38
  36. tree_sitter_analyzer/java_analyzer.py +0 -187
  37. {tree_sitter_analyzer-0.4.0.dist-info → tree_sitter_analyzer-0.6.1.dist-info}/WHEEL +0 -0
  38. {tree_sitter_analyzer-0.4.0.dist-info → tree_sitter_analyzer-0.6.1.dist-info}/entry_points.txt +0 -0
@@ -1,470 +1,470 @@
1
- #!/usr/bin/env python3
2
- """
3
- Data Models for Multi-Language Code Analysis
4
-
5
- Data classes for representing code structures extracted through
6
- Tree-sitter analysis across multiple programming languages.
7
- """
8
-
9
- from abc import ABC
10
- from collections.abc import Callable
11
- from dataclasses import dataclass, field
12
- from typing import TYPE_CHECKING, Any
13
-
14
- if TYPE_CHECKING:
15
- pass
16
-
17
-
18
- # Use dataclass with slots for Python 3.10+
19
- def dataclass_with_slots(*args: Any, **kwargs: Any) -> Callable[..., Any]:
20
- return dataclass(*args, slots=True, **kwargs) # type: ignore[no-any-return]
21
-
22
-
23
- # ========================================
24
- # Base Generic Models (Language Agnostic)
25
- # ========================================
26
-
27
-
28
- @dataclass(frozen=False)
29
- class CodeElement(ABC):
30
- """Base class for all code elements"""
31
-
32
- name: str
33
- start_line: int
34
- end_line: int
35
- raw_text: str = ""
36
- language: str = "unknown"
37
- docstring: str | None = None # JavaDoc/docstring for this element
38
-
39
-
40
- @dataclass(frozen=False)
41
- class Function(CodeElement):
42
- """Generic function/method representation"""
43
-
44
- parameters: list[str] = field(default_factory=list)
45
- return_type: str | None = None
46
- modifiers: list[str] = field(default_factory=list)
47
- is_async: bool = False
48
- is_static: bool = False
49
- is_private: bool = False
50
- is_public: bool = True
51
- is_constructor: bool = False
52
- visibility: str = "public"
53
- element_type: str = "function"
54
- # Java-specific fields for detailed analysis
55
- annotations: list[dict[str, Any]] = field(default_factory=list)
56
- throws: list[str] = field(default_factory=list)
57
- complexity_score: int = 1
58
- is_abstract: bool = False
59
- is_final: bool = False
60
-
61
-
62
- @dataclass(frozen=False)
63
- class Class(CodeElement):
64
- """Generic class representation"""
65
-
66
- class_type: str = "class"
67
- full_qualified_name: str | None = None
68
- package_name: str | None = None
69
- superclass: str | None = None
70
- interfaces: list[str] = field(default_factory=list)
71
- modifiers: list[str] = field(default_factory=list)
72
- visibility: str = "public"
73
- element_type: str = "class"
74
- methods: list[Function] = field(default_factory=list)
75
- # Java-specific fields for detailed analysis
76
- annotations: list[dict[str, Any]] = field(default_factory=list)
77
- is_nested: bool = False
78
- parent_class: str | None = None
79
- extends_class: str | None = None # Alias for superclass
80
- implements_interfaces: list[str] = field(
81
- default_factory=list
82
- ) # Alias for interfaces
83
-
84
-
85
- @dataclass(frozen=False)
86
- class Variable(CodeElement):
87
- """Generic variable representation"""
88
-
89
- variable_type: str | None = None
90
- modifiers: list[str] = field(default_factory=list)
91
- is_constant: bool = False
92
- is_static: bool = False
93
- visibility: str = "private"
94
- element_type: str = "variable"
95
- initializer: str | None = None
96
- # Java-specific fields for detailed analysis
97
- annotations: list[dict[str, Any]] = field(default_factory=list)
98
- is_final: bool = False
99
- field_type: str | None = None # Alias for variable_type
100
-
101
-
102
- @dataclass(frozen=False)
103
- class Import(CodeElement):
104
- """Generic import statement representation"""
105
-
106
- module_name: str = ""
107
- module_path: str = "" # Add module_path for compatibility with plugins
108
- imported_names: list[str] = field(default_factory=list)
109
- is_wildcard: bool = False
110
- is_static: bool = False
111
- element_type: str = "import"
112
- alias: str | None = None
113
- # Java-specific fields for detailed analysis
114
- imported_name: str = "" # Alias for name
115
- import_statement: str = "" # Full import statement
116
- line_number: int = 0 # Line number for compatibility
117
-
118
-
119
- @dataclass(frozen=False)
120
- class Package(CodeElement):
121
- """Generic package declaration representation"""
122
-
123
- element_type: str = "package"
124
-
125
-
126
- # ========================================
127
- # Java-Specific Models
128
- # ========================================
129
-
130
-
131
- @dataclass(frozen=False)
132
- class JavaAnnotation:
133
- """Java annotation representation"""
134
-
135
- name: str
136
- parameters: list[str] = field(default_factory=list)
137
- start_line: int = 0
138
- end_line: int = 0
139
- raw_text: str = ""
140
-
141
- def to_summary_item(self) -> dict[str, Any]:
142
- """要約アイテムとして辞書を返す"""
143
- return {
144
- "name": self.name,
145
- "type": "annotation",
146
- "lines": {"start": self.start_line, "end": self.end_line},
147
- }
148
-
149
-
150
- @dataclass(frozen=False)
151
- class JavaMethod:
152
- """Java method representation with comprehensive details"""
153
-
154
- name: str
155
- return_type: str | None = None
156
- parameters: list[str] = field(default_factory=list)
157
- modifiers: list[str] = field(default_factory=list)
158
- visibility: str = "package"
159
- annotations: list[JavaAnnotation] = field(default_factory=list)
160
- throws: list[str] = field(default_factory=list)
161
- start_line: int = 0
162
- end_line: int = 0
163
- is_constructor: bool = False
164
- is_abstract: bool = False
165
- is_static: bool = False
166
- is_final: bool = False
167
- complexity_score: int = 1
168
- file_path: str = ""
169
-
170
- def to_summary_item(self) -> dict[str, Any]:
171
- """要約アイテムとして辞書を返す"""
172
- return {
173
- "name": self.name,
174
- "type": "method",
175
- "lines": {"start": self.start_line, "end": self.end_line},
176
- }
177
-
178
-
179
- @dataclass(frozen=False)
180
- class JavaClass:
181
- """Java class representation with comprehensive details"""
182
-
183
- name: str
184
- full_qualified_name: str = ""
185
- package_name: str = ""
186
- class_type: str = "class"
187
- modifiers: list[str] = field(default_factory=list)
188
- visibility: str = "package"
189
- extends_class: str | None = None
190
- implements_interfaces: list[str] = field(default_factory=list)
191
- start_line: int = 0
192
- end_line: int = 0
193
- annotations: list[JavaAnnotation] = field(default_factory=list)
194
- is_nested: bool = False
195
- parent_class: str | None = None
196
- file_path: str = ""
197
-
198
- def to_summary_item(self) -> dict[str, Any]:
199
- """要約アイテムとして辞書を返す"""
200
- return {
201
- "name": self.name,
202
- "type": "class",
203
- "lines": {"start": self.start_line, "end": self.end_line},
204
- }
205
-
206
-
207
- @dataclass(frozen=False)
208
- class JavaField:
209
- """Java field representation"""
210
-
211
- name: str
212
- field_type: str = ""
213
- modifiers: list[str] = field(default_factory=list)
214
- visibility: str = "package"
215
- annotations: list[JavaAnnotation] = field(default_factory=list)
216
- start_line: int = 0
217
- end_line: int = 0
218
- is_static: bool = False
219
- is_final: bool = False
220
- file_path: str = ""
221
-
222
- def to_summary_item(self) -> dict[str, Any]:
223
- """要約アイテムとして辞書を返す"""
224
- return {
225
- "name": self.name,
226
- "type": "field",
227
- "lines": {"start": self.start_line, "end": self.end_line},
228
- }
229
-
230
-
231
- @dataclass(frozen=False)
232
- class JavaImport:
233
- """Java import statement representation"""
234
-
235
- name: str
236
- module_name: str = "" # Add module_name for compatibility
237
- imported_name: str = "" # Add imported_name for compatibility
238
- import_statement: str = "" # Add import_statement for compatibility
239
- line_number: int = 0 # Add line_number for compatibility
240
- is_static: bool = False
241
- is_wildcard: bool = False
242
- start_line: int = 0
243
- end_line: int = 0
244
-
245
- def to_summary_item(self) -> dict[str, Any]:
246
- """要約アイテムとして辞書を返す"""
247
- return {
248
- "name": self.name,
249
- "type": "import",
250
- "lines": {"start": self.start_line, "end": self.end_line},
251
- }
252
-
253
-
254
- @dataclass(frozen=False)
255
- class JavaPackage:
256
- """Java package declaration representation"""
257
-
258
- name: str
259
- start_line: int = 0
260
- end_line: int = 0
261
-
262
-
263
- @dataclass(frozen=False)
264
- class AnalysisResult:
265
- """Comprehensive analysis result container"""
266
-
267
- file_path: str
268
- language: str = "unknown" # Add language field for new architecture compatibility
269
- line_count: int = 0 # Add line_count for compatibility
270
- elements: list[CodeElement] = field(
271
- default_factory=list
272
- ) # Generic elements for new architecture
273
- node_count: int = 0 # Node count for new architecture
274
- query_results: dict[str, Any] = field(
275
- default_factory=dict
276
- ) # Query results for new architecture
277
- source_code: str = "" # Source code for new architecture
278
- package: JavaPackage | None = None
279
- imports: list[JavaImport] = field(default_factory=list)
280
- classes: list[JavaClass] = field(default_factory=list)
281
- methods: list[JavaMethod] = field(default_factory=list)
282
- fields: list[JavaField] = field(default_factory=list)
283
- annotations: list[JavaAnnotation] = field(default_factory=list)
284
- analysis_time: float = 0.0
285
- success: bool = True
286
- error_message: str | None = None
287
-
288
- def to_dict(self) -> dict[str, Any]:
289
- """Convert analysis result to dictionary for serialization"""
290
- return {
291
- "file_path": self.file_path,
292
- "line_count": self.line_count,
293
- "package": {"name": self.package.name} if self.package else None,
294
- "imports": [
295
- {
296
- "name": imp.name,
297
- "is_static": imp.is_static,
298
- "is_wildcard": imp.is_wildcard,
299
- }
300
- for imp in self.imports
301
- ],
302
- "classes": [
303
- {"name": cls.name, "type": cls.class_type, "package": cls.package_name}
304
- for cls in self.classes
305
- ],
306
- "methods": [
307
- {
308
- "name": method.name,
309
- "return_type": method.return_type,
310
- "parameters": method.parameters,
311
- }
312
- for method in self.methods
313
- ],
314
- "fields": [
315
- {"name": field.name, "type": field.field_type} for field in self.fields
316
- ],
317
- "annotations": [{"name": ann.name} for ann in self.annotations],
318
- "analysis_time": self.analysis_time,
319
- "success": self.success,
320
- "error_message": self.error_message,
321
- }
322
-
323
- def to_summary_dict(self, types: list[str] | None = None) -> dict[str, Any]:
324
- """
325
- 分析結果の要約を辞書として返します。
326
- 指定された型('classes', 'methods', 'fields'など)の要素のみを含みます。
327
- """
328
- if types is None:
329
- types = ["classes", "methods"] # デフォルト値
330
-
331
- summary: dict[str, Any] = {"file_path": self.file_path, "summary_elements": []}
332
-
333
- all_elements: dict[str, list[Any]] = {
334
- "imports": self.imports,
335
- "classes": self.classes,
336
- "methods": self.methods,
337
- "fields": self.fields,
338
- "annotations": self.annotations,
339
- }
340
-
341
- for type_name, elements in all_elements.items():
342
- if "all" in types or type_name in types:
343
- for element in elements:
344
- # 各要素モデルの to_summary_item() を呼び出し
345
- summary["summary_elements"].append(element.to_summary_item())
346
-
347
- return summary
348
-
349
- def get_summary(self) -> dict[str, Any]:
350
- """Get analysis summary statistics"""
351
- return {
352
- "file_path": self.file_path,
353
- "line_count": self.line_count,
354
- "class_count": len(self.classes),
355
- "method_count": len(self.methods),
356
- "field_count": len(self.fields),
357
- "import_count": len(self.imports),
358
- "annotation_count": len(self.annotations),
359
- "success": self.success,
360
- "analysis_time": self.analysis_time,
361
- }
362
-
363
- def to_mcp_format(self) -> dict[str, Any]:
364
- """
365
- MCP形式での出力を生成
366
-
367
- Returns:
368
- MCP形式の分析結果辞書
369
- """
370
- # packageの安全な処理
371
- package_info = None
372
- if self.package:
373
- if hasattr(self.package, "name"):
374
- package_info = {"name": self.package.name}
375
- elif isinstance(self.package, dict):
376
- package_info = self.package
377
- else:
378
- package_info = {"name": str(self.package)}
379
-
380
- # 安全なアイテム処理ヘルパー関数
381
- def safe_get_attr(obj: Any, attr: str, default: Any = "") -> Any:
382
- if hasattr(obj, attr):
383
- return getattr(obj, attr)
384
- elif isinstance(obj, dict):
385
- return obj.get(attr, default)
386
- else:
387
- return default
388
-
389
- return {
390
- "file_path": self.file_path,
391
- "structure": {
392
- "package": package_info,
393
- "imports": [
394
- {
395
- "name": safe_get_attr(imp, "name"),
396
- "is_static": safe_get_attr(imp, "is_static", False),
397
- "is_wildcard": safe_get_attr(imp, "is_wildcard", False),
398
- "line_range": {
399
- "start": safe_get_attr(imp, "start_line", 0),
400
- "end": safe_get_attr(imp, "end_line", 0),
401
- },
402
- }
403
- for imp in self.imports
404
- ],
405
- "classes": [
406
- {
407
- "name": safe_get_attr(cls, "name"),
408
- "type": safe_get_attr(cls, "class_type"),
409
- "package": safe_get_attr(cls, "package_name"),
410
- "line_range": {
411
- "start": safe_get_attr(cls, "start_line", 0),
412
- "end": safe_get_attr(cls, "end_line", 0),
413
- },
414
- }
415
- for cls in self.classes
416
- ],
417
- "methods": [
418
- {
419
- "name": safe_get_attr(method, "name"),
420
- "return_type": safe_get_attr(method, "return_type"),
421
- "parameters": safe_get_attr(method, "parameters", []),
422
- "line_range": {
423
- "start": safe_get_attr(method, "start_line", 0),
424
- "end": safe_get_attr(method, "end_line", 0),
425
- },
426
- }
427
- for method in self.methods
428
- ],
429
- "fields": [
430
- {
431
- "name": safe_get_attr(field, "name"),
432
- "type": safe_get_attr(field, "field_type"),
433
- "line_range": {
434
- "start": safe_get_attr(field, "start_line", 0),
435
- "end": safe_get_attr(field, "end_line", 0),
436
- },
437
- }
438
- for field in self.fields
439
- ],
440
- "annotations": [
441
- {
442
- "name": safe_get_attr(ann, "name"),
443
- "line_range": {
444
- "start": safe_get_attr(ann, "start_line", 0),
445
- "end": safe_get_attr(ann, "end_line", 0),
446
- },
447
- }
448
- for ann in self.annotations
449
- ],
450
- },
451
- "metadata": {
452
- "line_count": self.line_count,
453
- "class_count": len(self.classes),
454
- "method_count": len(self.methods),
455
- "field_count": len(self.fields),
456
- "import_count": len(self.imports),
457
- "annotation_count": len(self.annotations),
458
- "analysis_time": self.analysis_time,
459
- "success": self.success,
460
- "error_message": self.error_message,
461
- },
462
- }
463
-
464
- def get_statistics(self) -> dict[str, Any]:
465
- """Get detailed statistics (alias for get_summary)"""
466
- return self.get_summary()
467
-
468
- def to_json(self) -> dict[str, Any]:
469
- """Convert to JSON-serializable format (alias for to_dict)"""
470
- return self.to_dict()
1
+ #!/usr/bin/env python3
2
+ """
3
+ Data Models for Multi-Language Code Analysis
4
+
5
+ Data classes for representing code structures extracted through
6
+ Tree-sitter analysis across multiple programming languages.
7
+ """
8
+
9
+ from abc import ABC
10
+ from collections.abc import Callable
11
+ from dataclasses import dataclass, field
12
+ from typing import TYPE_CHECKING, Any
13
+
14
+ if TYPE_CHECKING:
15
+ pass
16
+
17
+
18
+ # Use dataclass with slots for Python 3.10+
19
+ def dataclass_with_slots(*args: Any, **kwargs: Any) -> Callable[..., Any]:
20
+ return dataclass(*args, slots=True, **kwargs) # type: ignore[no-any-return]
21
+
22
+
23
+ # ========================================
24
+ # Base Generic Models (Language Agnostic)
25
+ # ========================================
26
+
27
+
28
+ @dataclass(frozen=False)
29
+ class CodeElement(ABC):
30
+ """Base class for all code elements"""
31
+
32
+ name: str
33
+ start_line: int
34
+ end_line: int
35
+ raw_text: str = ""
36
+ language: str = "unknown"
37
+ docstring: str | None = None # JavaDoc/docstring for this element
38
+
39
+
40
+ @dataclass(frozen=False)
41
+ class Function(CodeElement):
42
+ """Generic function/method representation"""
43
+
44
+ parameters: list[str] = field(default_factory=list)
45
+ return_type: str | None = None
46
+ modifiers: list[str] = field(default_factory=list)
47
+ is_async: bool = False
48
+ is_static: bool = False
49
+ is_private: bool = False
50
+ is_public: bool = True
51
+ is_constructor: bool = False
52
+ visibility: str = "public"
53
+ element_type: str = "function"
54
+ # Java-specific fields for detailed analysis
55
+ annotations: list[dict[str, Any]] = field(default_factory=list)
56
+ throws: list[str] = field(default_factory=list)
57
+ complexity_score: int = 1
58
+ is_abstract: bool = False
59
+ is_final: bool = False
60
+
61
+
62
+ @dataclass(frozen=False)
63
+ class Class(CodeElement):
64
+ """Generic class representation"""
65
+
66
+ class_type: str = "class"
67
+ full_qualified_name: str | None = None
68
+ package_name: str | None = None
69
+ superclass: str | None = None
70
+ interfaces: list[str] = field(default_factory=list)
71
+ modifiers: list[str] = field(default_factory=list)
72
+ visibility: str = "public"
73
+ element_type: str = "class"
74
+ methods: list[Function] = field(default_factory=list)
75
+ # Java-specific fields for detailed analysis
76
+ annotations: list[dict[str, Any]] = field(default_factory=list)
77
+ is_nested: bool = False
78
+ parent_class: str | None = None
79
+ extends_class: str | None = None # Alias for superclass
80
+ implements_interfaces: list[str] = field(
81
+ default_factory=list
82
+ ) # Alias for interfaces
83
+
84
+
85
+ @dataclass(frozen=False)
86
+ class Variable(CodeElement):
87
+ """Generic variable representation"""
88
+
89
+ variable_type: str | None = None
90
+ modifiers: list[str] = field(default_factory=list)
91
+ is_constant: bool = False
92
+ is_static: bool = False
93
+ visibility: str = "private"
94
+ element_type: str = "variable"
95
+ initializer: str | None = None
96
+ # Java-specific fields for detailed analysis
97
+ annotations: list[dict[str, Any]] = field(default_factory=list)
98
+ is_final: bool = False
99
+ field_type: str | None = None # Alias for variable_type
100
+
101
+
102
+ @dataclass(frozen=False)
103
+ class Import(CodeElement):
104
+ """Generic import statement representation"""
105
+
106
+ module_name: str = ""
107
+ module_path: str = "" # Add module_path for compatibility with plugins
108
+ imported_names: list[str] = field(default_factory=list)
109
+ is_wildcard: bool = False
110
+ is_static: bool = False
111
+ element_type: str = "import"
112
+ alias: str | None = None
113
+ # Java-specific fields for detailed analysis
114
+ imported_name: str = "" # Alias for name
115
+ import_statement: str = "" # Full import statement
116
+ line_number: int = 0 # Line number for compatibility
117
+
118
+
119
+ @dataclass(frozen=False)
120
+ class Package(CodeElement):
121
+ """Generic package declaration representation"""
122
+
123
+ element_type: str = "package"
124
+
125
+
126
+ # ========================================
127
+ # Java-Specific Models
128
+ # ========================================
129
+
130
+
131
+ @dataclass(frozen=False)
132
+ class JavaAnnotation:
133
+ """Java annotation representation"""
134
+
135
+ name: str
136
+ parameters: list[str] = field(default_factory=list)
137
+ start_line: int = 0
138
+ end_line: int = 0
139
+ raw_text: str = ""
140
+
141
+ def to_summary_item(self) -> dict[str, Any]:
142
+ """要約アイテムとして辞書を返す"""
143
+ return {
144
+ "name": self.name,
145
+ "type": "annotation",
146
+ "lines": {"start": self.start_line, "end": self.end_line},
147
+ }
148
+
149
+
150
+ @dataclass(frozen=False)
151
+ class JavaMethod:
152
+ """Java method representation with comprehensive details"""
153
+
154
+ name: str
155
+ return_type: str | None = None
156
+ parameters: list[str] = field(default_factory=list)
157
+ modifiers: list[str] = field(default_factory=list)
158
+ visibility: str = "package"
159
+ annotations: list[JavaAnnotation] = field(default_factory=list)
160
+ throws: list[str] = field(default_factory=list)
161
+ start_line: int = 0
162
+ end_line: int = 0
163
+ is_constructor: bool = False
164
+ is_abstract: bool = False
165
+ is_static: bool = False
166
+ is_final: bool = False
167
+ complexity_score: int = 1
168
+ file_path: str = ""
169
+
170
+ def to_summary_item(self) -> dict[str, Any]:
171
+ """要約アイテムとして辞書を返す"""
172
+ return {
173
+ "name": self.name,
174
+ "type": "method",
175
+ "lines": {"start": self.start_line, "end": self.end_line},
176
+ }
177
+
178
+
179
+ @dataclass(frozen=False)
180
+ class JavaClass:
181
+ """Java class representation with comprehensive details"""
182
+
183
+ name: str
184
+ full_qualified_name: str = ""
185
+ package_name: str = ""
186
+ class_type: str = "class"
187
+ modifiers: list[str] = field(default_factory=list)
188
+ visibility: str = "package"
189
+ extends_class: str | None = None
190
+ implements_interfaces: list[str] = field(default_factory=list)
191
+ start_line: int = 0
192
+ end_line: int = 0
193
+ annotations: list[JavaAnnotation] = field(default_factory=list)
194
+ is_nested: bool = False
195
+ parent_class: str | None = None
196
+ file_path: str = ""
197
+
198
+ def to_summary_item(self) -> dict[str, Any]:
199
+ """要約アイテムとして辞書を返す"""
200
+ return {
201
+ "name": self.name,
202
+ "type": "class",
203
+ "lines": {"start": self.start_line, "end": self.end_line},
204
+ }
205
+
206
+
207
+ @dataclass(frozen=False)
208
+ class JavaField:
209
+ """Java field representation"""
210
+
211
+ name: str
212
+ field_type: str = ""
213
+ modifiers: list[str] = field(default_factory=list)
214
+ visibility: str = "package"
215
+ annotations: list[JavaAnnotation] = field(default_factory=list)
216
+ start_line: int = 0
217
+ end_line: int = 0
218
+ is_static: bool = False
219
+ is_final: bool = False
220
+ file_path: str = ""
221
+
222
+ def to_summary_item(self) -> dict[str, Any]:
223
+ """要約アイテムとして辞書を返す"""
224
+ return {
225
+ "name": self.name,
226
+ "type": "field",
227
+ "lines": {"start": self.start_line, "end": self.end_line},
228
+ }
229
+
230
+
231
+ @dataclass(frozen=False)
232
+ class JavaImport:
233
+ """Java import statement representation"""
234
+
235
+ name: str
236
+ module_name: str = "" # Add module_name for compatibility
237
+ imported_name: str = "" # Add imported_name for compatibility
238
+ import_statement: str = "" # Add import_statement for compatibility
239
+ line_number: int = 0 # Add line_number for compatibility
240
+ is_static: bool = False
241
+ is_wildcard: bool = False
242
+ start_line: int = 0
243
+ end_line: int = 0
244
+
245
+ def to_summary_item(self) -> dict[str, Any]:
246
+ """要約アイテムとして辞書を返す"""
247
+ return {
248
+ "name": self.name,
249
+ "type": "import",
250
+ "lines": {"start": self.start_line, "end": self.end_line},
251
+ }
252
+
253
+
254
+ @dataclass(frozen=False)
255
+ class JavaPackage:
256
+ """Java package declaration representation"""
257
+
258
+ name: str
259
+ start_line: int = 0
260
+ end_line: int = 0
261
+
262
+
263
+ @dataclass(frozen=False)
264
+ class AnalysisResult:
265
+ """Comprehensive analysis result container"""
266
+
267
+ file_path: str
268
+ language: str = "unknown" # Add language field for new architecture compatibility
269
+ line_count: int = 0 # Add line_count for compatibility
270
+ elements: list[CodeElement] = field(
271
+ default_factory=list
272
+ ) # Generic elements for new architecture
273
+ node_count: int = 0 # Node count for new architecture
274
+ query_results: dict[str, Any] = field(
275
+ default_factory=dict
276
+ ) # Query results for new architecture
277
+ source_code: str = "" # Source code for new architecture
278
+ package: JavaPackage | None = None
279
+ imports: list[JavaImport] = field(default_factory=list)
280
+ classes: list[JavaClass] = field(default_factory=list)
281
+ methods: list[JavaMethod] = field(default_factory=list)
282
+ fields: list[JavaField] = field(default_factory=list)
283
+ annotations: list[JavaAnnotation] = field(default_factory=list)
284
+ analysis_time: float = 0.0
285
+ success: bool = True
286
+ error_message: str | None = None
287
+
288
+ def to_dict(self) -> dict[str, Any]:
289
+ """Convert analysis result to dictionary for serialization"""
290
+ return {
291
+ "file_path": self.file_path,
292
+ "line_count": self.line_count,
293
+ "package": {"name": self.package.name} if self.package else None,
294
+ "imports": [
295
+ {
296
+ "name": imp.name,
297
+ "is_static": imp.is_static,
298
+ "is_wildcard": imp.is_wildcard,
299
+ }
300
+ for imp in self.imports
301
+ ],
302
+ "classes": [
303
+ {"name": cls.name, "type": cls.class_type, "package": cls.package_name}
304
+ for cls in self.classes
305
+ ],
306
+ "methods": [
307
+ {
308
+ "name": method.name,
309
+ "return_type": method.return_type,
310
+ "parameters": method.parameters,
311
+ }
312
+ for method in self.methods
313
+ ],
314
+ "fields": [
315
+ {"name": field.name, "type": field.field_type} for field in self.fields
316
+ ],
317
+ "annotations": [{"name": ann.name} for ann in self.annotations],
318
+ "analysis_time": self.analysis_time,
319
+ "success": self.success,
320
+ "error_message": self.error_message,
321
+ }
322
+
323
+ def to_summary_dict(self, types: list[str] | None = None) -> dict[str, Any]:
324
+ """
325
+ 分析結果の要約を辞書として返します。
326
+ 指定された型('classes', 'methods', 'fields'など)の要素のみを含みます。
327
+ """
328
+ if types is None:
329
+ types = ["classes", "methods"] # デフォルト値
330
+
331
+ summary: dict[str, Any] = {"file_path": self.file_path, "summary_elements": []}
332
+
333
+ all_elements: dict[str, list[Any]] = {
334
+ "imports": self.imports,
335
+ "classes": self.classes,
336
+ "methods": self.methods,
337
+ "fields": self.fields,
338
+ "annotations": self.annotations,
339
+ }
340
+
341
+ for type_name, elements in all_elements.items():
342
+ if "all" in types or type_name in types:
343
+ for element in elements:
344
+ # 各要素モデルの to_summary_item() を呼び出し
345
+ summary["summary_elements"].append(element.to_summary_item())
346
+
347
+ return summary
348
+
349
+ def get_summary(self) -> dict[str, Any]:
350
+ """Get analysis summary statistics"""
351
+ return {
352
+ "file_path": self.file_path,
353
+ "line_count": self.line_count,
354
+ "class_count": len(self.classes),
355
+ "method_count": len(self.methods),
356
+ "field_count": len(self.fields),
357
+ "import_count": len(self.imports),
358
+ "annotation_count": len(self.annotations),
359
+ "success": self.success,
360
+ "analysis_time": self.analysis_time,
361
+ }
362
+
363
+ def to_mcp_format(self) -> dict[str, Any]:
364
+ """
365
+ MCP形式での出力を生成
366
+
367
+ Returns:
368
+ MCP形式の分析結果辞書
369
+ """
370
+ # packageの安全な処理
371
+ package_info = None
372
+ if self.package:
373
+ if hasattr(self.package, "name"):
374
+ package_info = {"name": self.package.name}
375
+ elif isinstance(self.package, dict):
376
+ package_info = self.package
377
+ else:
378
+ package_info = {"name": str(self.package)}
379
+
380
+ # 安全なアイテム処理ヘルパー関数
381
+ def safe_get_attr(obj: Any, attr: str, default: Any = "") -> Any:
382
+ if hasattr(obj, attr):
383
+ return getattr(obj, attr)
384
+ elif isinstance(obj, dict):
385
+ return obj.get(attr, default)
386
+ else:
387
+ return default
388
+
389
+ return {
390
+ "file_path": self.file_path,
391
+ "structure": {
392
+ "package": package_info,
393
+ "imports": [
394
+ {
395
+ "name": safe_get_attr(imp, "name"),
396
+ "is_static": safe_get_attr(imp, "is_static", False),
397
+ "is_wildcard": safe_get_attr(imp, "is_wildcard", False),
398
+ "line_range": {
399
+ "start": safe_get_attr(imp, "start_line", 0),
400
+ "end": safe_get_attr(imp, "end_line", 0),
401
+ },
402
+ }
403
+ for imp in self.imports
404
+ ],
405
+ "classes": [
406
+ {
407
+ "name": safe_get_attr(cls, "name"),
408
+ "type": safe_get_attr(cls, "class_type"),
409
+ "package": safe_get_attr(cls, "package_name"),
410
+ "line_range": {
411
+ "start": safe_get_attr(cls, "start_line", 0),
412
+ "end": safe_get_attr(cls, "end_line", 0),
413
+ },
414
+ }
415
+ for cls in self.classes
416
+ ],
417
+ "methods": [
418
+ {
419
+ "name": safe_get_attr(method, "name"),
420
+ "return_type": safe_get_attr(method, "return_type"),
421
+ "parameters": safe_get_attr(method, "parameters", []),
422
+ "line_range": {
423
+ "start": safe_get_attr(method, "start_line", 0),
424
+ "end": safe_get_attr(method, "end_line", 0),
425
+ },
426
+ }
427
+ for method in self.methods
428
+ ],
429
+ "fields": [
430
+ {
431
+ "name": safe_get_attr(field, "name"),
432
+ "type": safe_get_attr(field, "field_type"),
433
+ "line_range": {
434
+ "start": safe_get_attr(field, "start_line", 0),
435
+ "end": safe_get_attr(field, "end_line", 0),
436
+ },
437
+ }
438
+ for field in self.fields
439
+ ],
440
+ "annotations": [
441
+ {
442
+ "name": safe_get_attr(ann, "name"),
443
+ "line_range": {
444
+ "start": safe_get_attr(ann, "start_line", 0),
445
+ "end": safe_get_attr(ann, "end_line", 0),
446
+ },
447
+ }
448
+ for ann in self.annotations
449
+ ],
450
+ },
451
+ "metadata": {
452
+ "line_count": self.line_count,
453
+ "class_count": len(self.classes),
454
+ "method_count": len(self.methods),
455
+ "field_count": len(self.fields),
456
+ "import_count": len(self.imports),
457
+ "annotation_count": len(self.annotations),
458
+ "analysis_time": self.analysis_time,
459
+ "success": self.success,
460
+ "error_message": self.error_message,
461
+ },
462
+ }
463
+
464
+ def get_statistics(self) -> dict[str, Any]:
465
+ """Get detailed statistics (alias for get_summary)"""
466
+ return self.get_summary()
467
+
468
+ def to_json(self) -> dict[str, Any]:
469
+ """Convert to JSON-serializable format (alias for to_dict)"""
470
+ return self.to_dict()