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