auto-coder 0.1.326__py3-none-any.whl → 0.1.328__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 auto-coder might be problematic. Click here for more details.
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/METADATA +1 -1
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/RECORD +28 -16
- autocoder/common/__init__.py +5 -0
- autocoder/common/auto_coder_lang.py +16 -0
- autocoder/common/stream_out_type.py +6 -0
- autocoder/common/v2/code_editblock_manager.py +92 -8
- autocoder/compilers/__init__.py +51 -0
- autocoder/compilers/base_compiler.py +107 -0
- autocoder/compilers/compiler_config_api.py +365 -0
- autocoder/compilers/compiler_config_manager.py +305 -0
- autocoder/compilers/compiler_factory.py +271 -0
- autocoder/compilers/java_compiler.py +680 -0
- autocoder/compilers/models.py +210 -0
- autocoder/compilers/provided_compiler.py +343 -0
- autocoder/compilers/python_compiler.py +413 -0
- autocoder/compilers/reactjs_compiler.py +491 -0
- autocoder/compilers/shadow_compiler.py +42 -0
- autocoder/compilers/vue_compiler.py +548 -0
- autocoder/events/event_content.py +29 -0
- autocoder/index/index.py +43 -9
- autocoder/memory/active_context_manager.py +3 -3
- autocoder/memory/active_package.py +2 -2
- autocoder/shadows/shadow_manager.py +251 -4
- autocoder/version.py +1 -1
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.326.dist-info → auto_coder-0.1.328.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for compiling Java code.
|
|
3
|
+
This module provides functionality to compile Java code and report compilation errors.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import subprocess
|
|
8
|
+
import tempfile
|
|
9
|
+
import time
|
|
10
|
+
import re
|
|
11
|
+
from typing import Dict, List, Any, Optional, Tuple
|
|
12
|
+
|
|
13
|
+
from autocoder.compilers.base_compiler import BaseCompiler
|
|
14
|
+
from autocoder.compilers.models import (
|
|
15
|
+
CompilationError,
|
|
16
|
+
FileCompilationResult,
|
|
17
|
+
ProjectCompilationResult,
|
|
18
|
+
CompilationErrorPosition,
|
|
19
|
+
CompilationErrorSeverity
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
class JavaCompiler(BaseCompiler):
|
|
23
|
+
"""
|
|
24
|
+
A class that provides compilation functionality for Java code.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, verbose: bool = False):
|
|
28
|
+
"""
|
|
29
|
+
Initialize the JavaCompiler.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
verbose (bool): Whether to display verbose output.
|
|
33
|
+
"""
|
|
34
|
+
super().__init__(verbose)
|
|
35
|
+
|
|
36
|
+
def get_supported_extensions(self) -> List[str]:
|
|
37
|
+
"""
|
|
38
|
+
Get the list of file extensions supported by this compiler.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
List[str]: List of supported file extensions.
|
|
42
|
+
"""
|
|
43
|
+
return ['.java']
|
|
44
|
+
|
|
45
|
+
def _check_dependencies(self) -> bool:
|
|
46
|
+
"""
|
|
47
|
+
Check if required dependencies (javac) are installed.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
bool: True if all dependencies are available, False otherwise.
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
# Check if javac is installed
|
|
54
|
+
process = subprocess.run(
|
|
55
|
+
['javac', '-version'],
|
|
56
|
+
stdout=subprocess.PIPE,
|
|
57
|
+
stderr=subprocess.PIPE,
|
|
58
|
+
text=True
|
|
59
|
+
)
|
|
60
|
+
return process.returncode == 0
|
|
61
|
+
except (subprocess.SubprocessError, FileNotFoundError):
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
def _parse_javac_error(self, error_line: str, file_path: Optional[str] = None) -> Optional[CompilationError]:
|
|
65
|
+
"""
|
|
66
|
+
Parse a javac error message into a CompilationError object.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
error_line (str): Error line from javac output
|
|
70
|
+
file_path (Optional[str]): The file path to use if not found in error message
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Optional[CompilationError]: Parsed error or None if couldn't parse
|
|
74
|
+
"""
|
|
75
|
+
# Common javac error format: file_path:line: error: message
|
|
76
|
+
match = re.match(r'(.*?):(\d+)(?::(\d+))?: (error|warning): (.*)', error_line)
|
|
77
|
+
if match:
|
|
78
|
+
error_file = match.group(1)
|
|
79
|
+
line = int(match.group(2))
|
|
80
|
+
column = int(match.group(3)) if match.group(3) else None
|
|
81
|
+
severity_str = match.group(4)
|
|
82
|
+
message = match.group(5)
|
|
83
|
+
|
|
84
|
+
# Use provided file_path if error_file is not absolute
|
|
85
|
+
if file_path and not os.path.isabs(error_file):
|
|
86
|
+
# Try to find the full path
|
|
87
|
+
if os.path.exists(os.path.join(os.path.dirname(file_path), error_file)):
|
|
88
|
+
error_file = os.path.join(os.path.dirname(file_path), error_file)
|
|
89
|
+
else:
|
|
90
|
+
error_file = file_path
|
|
91
|
+
|
|
92
|
+
return CompilationError(
|
|
93
|
+
message=message,
|
|
94
|
+
severity=CompilationErrorSeverity.ERROR if severity_str == 'error' else CompilationErrorSeverity.WARNING,
|
|
95
|
+
position=CompilationErrorPosition(
|
|
96
|
+
line=line,
|
|
97
|
+
column=column
|
|
98
|
+
),
|
|
99
|
+
file_path=error_file,
|
|
100
|
+
code="java-compilation-error"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
def compile_file(self, file_path: str) -> Dict[str, Any]:
|
|
106
|
+
"""
|
|
107
|
+
Compile a single Java file.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
file_path (str): Path to the file to compile.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Dict[str, Any]: Compilation results.
|
|
114
|
+
"""
|
|
115
|
+
if not os.path.exists(file_path):
|
|
116
|
+
return FileCompilationResult(
|
|
117
|
+
file_path=file_path,
|
|
118
|
+
success=False,
|
|
119
|
+
language="java",
|
|
120
|
+
error_message=f"File not found: {file_path}"
|
|
121
|
+
).model_dump()
|
|
122
|
+
|
|
123
|
+
if not self.is_supported_file(file_path):
|
|
124
|
+
return FileCompilationResult(
|
|
125
|
+
file_path=file_path,
|
|
126
|
+
success=False,
|
|
127
|
+
language="java",
|
|
128
|
+
error_message=f"Unsupported file type: {file_path}"
|
|
129
|
+
).model_dump()
|
|
130
|
+
|
|
131
|
+
if not self._check_dependencies():
|
|
132
|
+
return FileCompilationResult(
|
|
133
|
+
file_path=file_path,
|
|
134
|
+
success=False,
|
|
135
|
+
language="java",
|
|
136
|
+
error_message="Java compiler (javac) not found. Please make sure JDK is installed."
|
|
137
|
+
).model_dump()
|
|
138
|
+
|
|
139
|
+
start_time = time.time()
|
|
140
|
+
errors = []
|
|
141
|
+
error_count = 0
|
|
142
|
+
warning_count = 0
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
# Create a temporary directory for output
|
|
146
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
147
|
+
# Run javac on the file
|
|
148
|
+
cmd = ['javac', '-d', temp_dir, file_path]
|
|
149
|
+
|
|
150
|
+
process = subprocess.run(
|
|
151
|
+
cmd,
|
|
152
|
+
stdout=subprocess.PIPE,
|
|
153
|
+
stderr=subprocess.PIPE,
|
|
154
|
+
text=True
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Parse compilation errors
|
|
158
|
+
if process.returncode != 0:
|
|
159
|
+
success = False
|
|
160
|
+
# Parse error output
|
|
161
|
+
error_lines = process.stderr.splitlines()
|
|
162
|
+
|
|
163
|
+
for line in error_lines:
|
|
164
|
+
if not line.strip():
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
error = self._parse_javac_error(line, file_path)
|
|
168
|
+
if error:
|
|
169
|
+
errors.append(error)
|
|
170
|
+
if error.severity == CompilationErrorSeverity.ERROR:
|
|
171
|
+
error_count += 1
|
|
172
|
+
elif error.severity == CompilationErrorSeverity.WARNING:
|
|
173
|
+
warning_count += 1
|
|
174
|
+
else:
|
|
175
|
+
success = True
|
|
176
|
+
|
|
177
|
+
# Get output file location (class file)
|
|
178
|
+
output_file = None
|
|
179
|
+
class_name = os.path.splitext(os.path.basename(file_path))[0]
|
|
180
|
+
class_file = os.path.join(temp_dir, f"{class_name}.class")
|
|
181
|
+
|
|
182
|
+
if os.path.exists(class_file):
|
|
183
|
+
output_file = class_file
|
|
184
|
+
|
|
185
|
+
except Exception as e:
|
|
186
|
+
return FileCompilationResult(
|
|
187
|
+
file_path=file_path,
|
|
188
|
+
success=False,
|
|
189
|
+
language="java",
|
|
190
|
+
error_message=f"Error during compilation: {str(e)}"
|
|
191
|
+
).model_dump()
|
|
192
|
+
|
|
193
|
+
# Calculate execution time
|
|
194
|
+
execution_time_ms = int((time.time() - start_time) * 1000)
|
|
195
|
+
|
|
196
|
+
# Create the result
|
|
197
|
+
result = FileCompilationResult(
|
|
198
|
+
file_path=file_path,
|
|
199
|
+
success=success,
|
|
200
|
+
language="java",
|
|
201
|
+
errors=errors,
|
|
202
|
+
error_count=error_count,
|
|
203
|
+
warning_count=warning_count,
|
|
204
|
+
info_count=0,
|
|
205
|
+
execution_time_ms=execution_time_ms,
|
|
206
|
+
output_file=output_file
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
return result.model_dump()
|
|
210
|
+
|
|
211
|
+
def _is_maven_project(self, project_path: str) -> bool:
|
|
212
|
+
"""
|
|
213
|
+
Check if a directory is a Maven project.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
project_path (str): Path to the project directory.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
bool: True if it's a Maven project (has pom.xml), False otherwise.
|
|
220
|
+
"""
|
|
221
|
+
return os.path.exists(os.path.join(project_path, 'pom.xml'))
|
|
222
|
+
|
|
223
|
+
def _is_gradle_project(self, project_path: str) -> bool:
|
|
224
|
+
"""
|
|
225
|
+
Check if a directory is a Gradle project.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
project_path (str): Path to the project directory.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
bool: True if it's a Gradle project (has build.gradle), False otherwise.
|
|
232
|
+
"""
|
|
233
|
+
return (os.path.exists(os.path.join(project_path, 'build.gradle')) or
|
|
234
|
+
os.path.exists(os.path.join(project_path, 'build.gradle.kts')))
|
|
235
|
+
|
|
236
|
+
def _compile_maven_project(self, project_path: str) -> Dict[str, Any]:
|
|
237
|
+
"""
|
|
238
|
+
Compile a Maven project.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
project_path (str): Path to the Maven project directory.
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
Dict[str, Any]: Compilation results.
|
|
245
|
+
"""
|
|
246
|
+
errors = []
|
|
247
|
+
error_count = 0
|
|
248
|
+
warning_count = 0
|
|
249
|
+
success = False
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
# Run Maven compile
|
|
253
|
+
cmd = ['mvn', 'compile', '-B']
|
|
254
|
+
|
|
255
|
+
process = subprocess.run(
|
|
256
|
+
cmd,
|
|
257
|
+
cwd=project_path,
|
|
258
|
+
stdout=subprocess.PIPE,
|
|
259
|
+
stderr=subprocess.PIPE,
|
|
260
|
+
text=True
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
success = process.returncode == 0
|
|
264
|
+
|
|
265
|
+
# Parse Maven output for errors
|
|
266
|
+
if not success:
|
|
267
|
+
output = process.stdout + process.stderr
|
|
268
|
+
error_pattern = r'\[ERROR\] (.*?):(\d+)(?::(\d+))?: (.*)'
|
|
269
|
+
|
|
270
|
+
for line in output.splitlines():
|
|
271
|
+
match = re.search(error_pattern, line)
|
|
272
|
+
if match:
|
|
273
|
+
source_file = match.group(1)
|
|
274
|
+
line_number = int(match.group(2))
|
|
275
|
+
column = int(match.group(3)) if match.group(3) else None
|
|
276
|
+
message = match.group(4)
|
|
277
|
+
|
|
278
|
+
error = CompilationError(
|
|
279
|
+
message=message,
|
|
280
|
+
severity=CompilationErrorSeverity.ERROR,
|
|
281
|
+
position=CompilationErrorPosition(
|
|
282
|
+
line=line_number,
|
|
283
|
+
column=column
|
|
284
|
+
),
|
|
285
|
+
file_path=source_file,
|
|
286
|
+
code="maven-compile-error"
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
errors.append(error)
|
|
290
|
+
error_count += 1
|
|
291
|
+
|
|
292
|
+
# Check for warnings too
|
|
293
|
+
warning_pattern = r'\[WARNING\] (.*?):(\d+)(?::(\d+))?: (.*)'
|
|
294
|
+
output = process.stdout + process.stderr
|
|
295
|
+
|
|
296
|
+
for line in output.splitlines():
|
|
297
|
+
match = re.search(warning_pattern, line)
|
|
298
|
+
if match:
|
|
299
|
+
source_file = match.group(1)
|
|
300
|
+
line_number = int(match.group(2))
|
|
301
|
+
column = int(match.group(3)) if match.group(3) else None
|
|
302
|
+
message = match.group(4)
|
|
303
|
+
|
|
304
|
+
warning = CompilationError(
|
|
305
|
+
message=message,
|
|
306
|
+
severity=CompilationErrorSeverity.WARNING,
|
|
307
|
+
position=CompilationErrorPosition(
|
|
308
|
+
line=line_number,
|
|
309
|
+
column=column
|
|
310
|
+
),
|
|
311
|
+
file_path=source_file,
|
|
312
|
+
code="maven-compile-warning"
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
errors.append(warning)
|
|
316
|
+
warning_count += 1
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
'success': success,
|
|
320
|
+
'errors': errors,
|
|
321
|
+
'error_count': error_count,
|
|
322
|
+
'warning_count': warning_count,
|
|
323
|
+
'output_directory': os.path.join(project_path, 'target', 'classes') if success else None
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
except Exception as e:
|
|
327
|
+
return {
|
|
328
|
+
'success': False,
|
|
329
|
+
'errors': [],
|
|
330
|
+
'error_count': 0,
|
|
331
|
+
'warning_count': 0,
|
|
332
|
+
'error_message': f"Error during Maven compilation: {str(e)}"
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
def _compile_gradle_project(self, project_path: str) -> Dict[str, Any]:
|
|
336
|
+
"""
|
|
337
|
+
Compile a Gradle project.
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
project_path (str): Path to the Gradle project directory.
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
Dict[str, Any]: Compilation results.
|
|
344
|
+
"""
|
|
345
|
+
errors = []
|
|
346
|
+
error_count = 0
|
|
347
|
+
warning_count = 0
|
|
348
|
+
success = False
|
|
349
|
+
|
|
350
|
+
try:
|
|
351
|
+
# Run Gradle build
|
|
352
|
+
cmd = ['./gradlew', 'compileJava', '--console=plain']
|
|
353
|
+
if not os.path.exists(os.path.join(project_path, 'gradlew')):
|
|
354
|
+
cmd = ['gradle', 'compileJava', '--console=plain']
|
|
355
|
+
|
|
356
|
+
process = subprocess.run(
|
|
357
|
+
cmd,
|
|
358
|
+
cwd=project_path,
|
|
359
|
+
stdout=subprocess.PIPE,
|
|
360
|
+
stderr=subprocess.PIPE,
|
|
361
|
+
text=True
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
success = process.returncode == 0
|
|
365
|
+
|
|
366
|
+
# Parse Gradle output for errors
|
|
367
|
+
if not success:
|
|
368
|
+
output = process.stdout + process.stderr
|
|
369
|
+
# Gradle error pattern: file_path:line: error: message
|
|
370
|
+
error_pattern = r'(.*?):(\d+)(?::(\d+))?: (error|warning): (.*)'
|
|
371
|
+
|
|
372
|
+
for line in output.splitlines():
|
|
373
|
+
match = re.search(error_pattern, line)
|
|
374
|
+
if match:
|
|
375
|
+
source_file = match.group(1)
|
|
376
|
+
line_number = int(match.group(2))
|
|
377
|
+
column = int(match.group(3)) if match.group(3) else None
|
|
378
|
+
severity_type = match.group(4)
|
|
379
|
+
message = match.group(5)
|
|
380
|
+
|
|
381
|
+
error = CompilationError(
|
|
382
|
+
message=message,
|
|
383
|
+
severity=CompilationErrorSeverity.ERROR if severity_type == 'error' else CompilationErrorSeverity.WARNING,
|
|
384
|
+
position=CompilationErrorPosition(
|
|
385
|
+
line=line_number,
|
|
386
|
+
column=column
|
|
387
|
+
),
|
|
388
|
+
file_path=source_file,
|
|
389
|
+
code="gradle-compile-error"
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
errors.append(error)
|
|
393
|
+
if severity_type == 'error':
|
|
394
|
+
error_count += 1
|
|
395
|
+
else:
|
|
396
|
+
warning_count += 1
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
'success': success,
|
|
400
|
+
'errors': errors,
|
|
401
|
+
'error_count': error_count,
|
|
402
|
+
'warning_count': warning_count,
|
|
403
|
+
'output_directory': os.path.join(project_path, 'build', 'classes') if success else None
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
except Exception as e:
|
|
407
|
+
return {
|
|
408
|
+
'success': False,
|
|
409
|
+
'errors': [],
|
|
410
|
+
'error_count': 0,
|
|
411
|
+
'warning_count': 0,
|
|
412
|
+
'error_message': f"Error during Gradle compilation: {str(e)}"
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
def _compile_standard_java_project(self, project_path: str) -> Dict[str, Any]:
|
|
416
|
+
"""
|
|
417
|
+
Compile a standard Java project (not using Maven or Gradle).
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
project_path (str): Path to the Java project directory.
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
Dict[str, Any]: Compilation results.
|
|
424
|
+
"""
|
|
425
|
+
errors = []
|
|
426
|
+
error_count = 0
|
|
427
|
+
warning_count = 0
|
|
428
|
+
success = True
|
|
429
|
+
file_results = {}
|
|
430
|
+
|
|
431
|
+
try:
|
|
432
|
+
# Create a temporary directory for output
|
|
433
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
434
|
+
# Find all Java files
|
|
435
|
+
java_files = []
|
|
436
|
+
for root, _, files in os.walk(project_path):
|
|
437
|
+
for file in files:
|
|
438
|
+
if file.endswith(".java"):
|
|
439
|
+
java_files.append(os.path.join(root, file))
|
|
440
|
+
|
|
441
|
+
if not java_files:
|
|
442
|
+
return {
|
|
443
|
+
'success': True,
|
|
444
|
+
'errors': [],
|
|
445
|
+
'error_count': 0,
|
|
446
|
+
'warning_count': 0,
|
|
447
|
+
'file_results': {},
|
|
448
|
+
'message': "No Java files found in the project"
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
# First try to compile all files together
|
|
452
|
+
all_files_cmd = ['javac', '-d', temp_dir] + java_files
|
|
453
|
+
|
|
454
|
+
process = subprocess.run(
|
|
455
|
+
all_files_cmd,
|
|
456
|
+
stdout=subprocess.PIPE,
|
|
457
|
+
stderr=subprocess.PIPE,
|
|
458
|
+
text=True
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
if process.returncode == 0:
|
|
462
|
+
# Successfully compiled all files together
|
|
463
|
+
return {
|
|
464
|
+
'success': True,
|
|
465
|
+
'errors': [],
|
|
466
|
+
'error_count': 0,
|
|
467
|
+
'warning_count': 0,
|
|
468
|
+
'file_results': {f: {'success': True, 'error_count': 0} for f in java_files},
|
|
469
|
+
'output_directory': temp_dir
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
# If all-at-once compilation failed, try compiling each file individually
|
|
473
|
+
for file_path in java_files:
|
|
474
|
+
file_result = self.compile_file(file_path)
|
|
475
|
+
file_results[file_path] = file_result
|
|
476
|
+
|
|
477
|
+
if not file_result['success']:
|
|
478
|
+
success = False
|
|
479
|
+
|
|
480
|
+
error_count += file_result['error_count']
|
|
481
|
+
warning_count += file_result['warning_count']
|
|
482
|
+
errors.extend(file_result['errors'])
|
|
483
|
+
|
|
484
|
+
return {
|
|
485
|
+
'success': success,
|
|
486
|
+
'errors': errors,
|
|
487
|
+
'error_count': error_count,
|
|
488
|
+
'warning_count': warning_count,
|
|
489
|
+
'file_results': file_results,
|
|
490
|
+
'output_directory': temp_dir if success else None
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
except Exception as e:
|
|
494
|
+
return {
|
|
495
|
+
'success': False,
|
|
496
|
+
'errors': [],
|
|
497
|
+
'error_count': 0,
|
|
498
|
+
'warning_count': 0,
|
|
499
|
+
'error_message': f"Error during Java compilation: {str(e)}"
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
def compile_project(self, project_path: str) -> Dict[str, Any]:
|
|
503
|
+
"""
|
|
504
|
+
Compile a Java project.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
project_path (str): Path to the project directory.
|
|
508
|
+
|
|
509
|
+
Returns:
|
|
510
|
+
Dict[str, Any]: Compilation results.
|
|
511
|
+
"""
|
|
512
|
+
if not os.path.exists(project_path):
|
|
513
|
+
return ProjectCompilationResult(
|
|
514
|
+
project_path=project_path,
|
|
515
|
+
success=False,
|
|
516
|
+
total_files=0,
|
|
517
|
+
error_message=f"Project directory not found: {project_path}"
|
|
518
|
+
).model_dump()
|
|
519
|
+
|
|
520
|
+
if not self._check_dependencies():
|
|
521
|
+
return ProjectCompilationResult(
|
|
522
|
+
project_path=project_path,
|
|
523
|
+
success=False,
|
|
524
|
+
total_files=0,
|
|
525
|
+
error_message="Java compiler (javac) not found. Please make sure JDK is installed."
|
|
526
|
+
).model_dump()
|
|
527
|
+
|
|
528
|
+
start_time = time.time()
|
|
529
|
+
|
|
530
|
+
# Determine project type and compile accordingly
|
|
531
|
+
if self._is_maven_project(project_path):
|
|
532
|
+
maven_result = self._compile_maven_project(project_path)
|
|
533
|
+
success = maven_result['success']
|
|
534
|
+
errors = maven_result.get('errors', [])
|
|
535
|
+
error_count = maven_result.get('error_count', 0)
|
|
536
|
+
warning_count = maven_result.get('warning_count', 0)
|
|
537
|
+
output_directory = maven_result.get('output_directory')
|
|
538
|
+
error_message = maven_result.get('error_message')
|
|
539
|
+
|
|
540
|
+
# Count Java files in src/main/java
|
|
541
|
+
java_dir = os.path.join(project_path, 'src', 'main', 'java')
|
|
542
|
+
total_files = 0
|
|
543
|
+
file_results = {}
|
|
544
|
+
|
|
545
|
+
if os.path.exists(java_dir):
|
|
546
|
+
for root, _, files in os.walk(java_dir):
|
|
547
|
+
for file in files:
|
|
548
|
+
if file.endswith(".java"):
|
|
549
|
+
java_file = os.path.join(root, file)
|
|
550
|
+
total_files += 1
|
|
551
|
+
|
|
552
|
+
# Create a file result for each Java file
|
|
553
|
+
file_errors = [e for e in errors if e.file_path == java_file]
|
|
554
|
+
file_results[java_file] = FileCompilationResult(
|
|
555
|
+
file_path=java_file,
|
|
556
|
+
success=len(file_errors) == 0,
|
|
557
|
+
language="java",
|
|
558
|
+
errors=file_errors,
|
|
559
|
+
error_count=len([e for e in file_errors if e.severity == CompilationErrorSeverity.ERROR]),
|
|
560
|
+
warning_count=len([e for e in file_errors if e.severity == CompilationErrorSeverity.WARNING]),
|
|
561
|
+
info_count=0
|
|
562
|
+
).model_dump()
|
|
563
|
+
|
|
564
|
+
elif self._is_gradle_project(project_path):
|
|
565
|
+
gradle_result = self._compile_gradle_project(project_path)
|
|
566
|
+
success = gradle_result['success']
|
|
567
|
+
errors = gradle_result.get('errors', [])
|
|
568
|
+
error_count = gradle_result.get('error_count', 0)
|
|
569
|
+
warning_count = gradle_result.get('warning_count', 0)
|
|
570
|
+
output_directory = gradle_result.get('output_directory')
|
|
571
|
+
error_message = gradle_result.get('error_message')
|
|
572
|
+
|
|
573
|
+
# Count Java files in src/main/java
|
|
574
|
+
java_dir = os.path.join(project_path, 'src', 'main', 'java')
|
|
575
|
+
total_files = 0
|
|
576
|
+
file_results = {}
|
|
577
|
+
|
|
578
|
+
if os.path.exists(java_dir):
|
|
579
|
+
for root, _, files in os.walk(java_dir):
|
|
580
|
+
for file in files:
|
|
581
|
+
if file.endswith(".java"):
|
|
582
|
+
java_file = os.path.join(root, file)
|
|
583
|
+
total_files += 1
|
|
584
|
+
|
|
585
|
+
# Create a file result for each Java file
|
|
586
|
+
file_errors = [e for e in errors if e.file_path == java_file]
|
|
587
|
+
file_results[java_file] = FileCompilationResult(
|
|
588
|
+
file_path=java_file,
|
|
589
|
+
success=len(file_errors) == 0,
|
|
590
|
+
language="java",
|
|
591
|
+
errors=file_errors,
|
|
592
|
+
error_count=len([e for e in file_errors if e.severity == CompilationErrorSeverity.ERROR]),
|
|
593
|
+
warning_count=len([e for e in file_errors if e.severity == CompilationErrorSeverity.WARNING]),
|
|
594
|
+
info_count=0
|
|
595
|
+
).model_dump()
|
|
596
|
+
|
|
597
|
+
else:
|
|
598
|
+
# Standard Java project
|
|
599
|
+
standard_result = self._compile_standard_java_project(project_path)
|
|
600
|
+
success = standard_result['success']
|
|
601
|
+
errors = standard_result.get('errors', [])
|
|
602
|
+
error_count = standard_result.get('error_count', 0)
|
|
603
|
+
warning_count = standard_result.get('warning_count', 0)
|
|
604
|
+
output_directory = standard_result.get('output_directory')
|
|
605
|
+
error_message = standard_result.get('error_message')
|
|
606
|
+
file_results = standard_result.get('file_results', {})
|
|
607
|
+
|
|
608
|
+
# Count total files
|
|
609
|
+
total_files = 0
|
|
610
|
+
for root, _, files in os.walk(project_path):
|
|
611
|
+
for file in files:
|
|
612
|
+
if file.endswith(".java"):
|
|
613
|
+
total_files += 1
|
|
614
|
+
|
|
615
|
+
# Calculate execution time
|
|
616
|
+
execution_time_ms = int((time.time() - start_time) * 1000)
|
|
617
|
+
|
|
618
|
+
# Count files with errors
|
|
619
|
+
files_with_errors = len([f for f in file_results.values() if f.get('error_count', 0) > 0])
|
|
620
|
+
|
|
621
|
+
# Create the project result
|
|
622
|
+
result = ProjectCompilationResult(
|
|
623
|
+
project_path=project_path,
|
|
624
|
+
success=success,
|
|
625
|
+
total_files=total_files,
|
|
626
|
+
files_with_errors=files_with_errors,
|
|
627
|
+
total_errors=error_count,
|
|
628
|
+
total_warnings=warning_count,
|
|
629
|
+
total_infos=0,
|
|
630
|
+
file_results={p: FileCompilationResult(**r) for p, r in file_results.items()},
|
|
631
|
+
error_message=error_message,
|
|
632
|
+
output_directory=output_directory
|
|
633
|
+
)
|
|
634
|
+
|
|
635
|
+
return result.model_dump()
|
|
636
|
+
|
|
637
|
+
def format_compile_result(self, compile_result: Dict[str, Any]) -> str:
|
|
638
|
+
"""
|
|
639
|
+
Format compilation results into a human-readable string.
|
|
640
|
+
|
|
641
|
+
Args:
|
|
642
|
+
compile_result (Dict[str, Any]): The compilation result dictionary.
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
str: A formatted string representation of the compilation results.
|
|
646
|
+
"""
|
|
647
|
+
if 'project_path' in compile_result:
|
|
648
|
+
# This is a project result
|
|
649
|
+
return ProjectCompilationResult(**compile_result).to_str()
|
|
650
|
+
else:
|
|
651
|
+
# This is a file result
|
|
652
|
+
return FileCompilationResult(**compile_result).to_str()
|
|
653
|
+
|
|
654
|
+
def compile_java_file(file_path: str, verbose: bool = False) -> Dict[str, Any]:
|
|
655
|
+
"""
|
|
656
|
+
Utility function to compile a single Java file.
|
|
657
|
+
|
|
658
|
+
Args:
|
|
659
|
+
file_path (str): Path to the file to compile.
|
|
660
|
+
verbose (bool): Whether to display verbose output.
|
|
661
|
+
|
|
662
|
+
Returns:
|
|
663
|
+
Dict[str, Any]: A dictionary containing compilation results.
|
|
664
|
+
"""
|
|
665
|
+
compiler = JavaCompiler(verbose=verbose)
|
|
666
|
+
return compiler.compile_file(file_path)
|
|
667
|
+
|
|
668
|
+
def compile_java_project(project_path: str, verbose: bool = False) -> Dict[str, Any]:
|
|
669
|
+
"""
|
|
670
|
+
Utility function to compile a Java project.
|
|
671
|
+
|
|
672
|
+
Args:
|
|
673
|
+
project_path (str): Path to the project directory.
|
|
674
|
+
verbose (bool): Whether to display verbose output.
|
|
675
|
+
|
|
676
|
+
Returns:
|
|
677
|
+
Dict[str, Any]: A dictionary containing compilation results.
|
|
678
|
+
"""
|
|
679
|
+
compiler = JavaCompiler(verbose=verbose)
|
|
680
|
+
return compiler.compile_project(project_path)
|