@voodocs/cli 0.4.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +431 -0
- package/lib/cli/__init__.py +53 -0
- package/lib/cli/benchmark.py +311 -0
- package/lib/cli/fix.py +244 -0
- package/lib/cli/generate.py +310 -0
- package/lib/cli/test_cli.py +215 -0
- package/lib/cli/validate.py +364 -0
- package/lib/darkarts/__init__.py +11 -5
- package/lib/darkarts/annotations/__init__.py +11 -3
- package/lib/darkarts/annotations/darkarts_parser.py +1 -1
- package/lib/darkarts/annotations/translator.py +32 -5
- package/lib/darkarts/annotations/types.py +15 -2
- package/lib/darkarts/cli_darkarts.py +143 -15
- package/lib/darkarts/context/__init__.py +11 -3
- package/lib/darkarts/context/ai_integrations.py +7 -21
- package/lib/darkarts/context/commands.py +1 -1
- package/lib/darkarts/context/diagram.py +8 -22
- package/lib/darkarts/context/models.py +7 -22
- package/lib/darkarts/context/module_utils.py +1 -1
- package/lib/darkarts/context/ui.py +1 -1
- package/lib/darkarts/context/validation.py +1 -1
- package/lib/darkarts/context/yaml_utils.py +8 -23
- package/lib/darkarts/core/__init__.py +12 -2
- package/lib/darkarts/core/interface.py +15 -1
- package/lib/darkarts/core/loader.py +16 -1
- package/lib/darkarts/core/plugin.py +15 -2
- package/lib/darkarts/core/registry.py +16 -1
- package/lib/darkarts/exceptions.py +16 -2
- package/lib/darkarts/plugins/voodocs/__init__.py +12 -2
- package/lib/darkarts/plugins/voodocs/ai_native_plugin.py +15 -4
- package/lib/darkarts/plugins/voodocs/annotation_validator.py +15 -2
- package/lib/darkarts/plugins/voodocs/api_spec_generator.py +15 -2
- package/lib/darkarts/plugins/voodocs/documentation_generator.py +15 -2
- package/lib/darkarts/plugins/voodocs/html_exporter.py +15 -2
- package/lib/darkarts/plugins/voodocs/instruction_generator.py +1 -1
- package/lib/darkarts/plugins/voodocs/pdf_exporter.py +15 -2
- package/lib/darkarts/plugins/voodocs/test_generator.py +15 -2
- package/lib/darkarts/telemetry.py +15 -2
- package/lib/darkarts/validation/README.md +147 -0
- package/lib/darkarts/validation/__init__.py +91 -0
- package/lib/darkarts/validation/autofix.py +297 -0
- package/lib/darkarts/validation/benchmark.py +426 -0
- package/lib/darkarts/validation/benchmark_wrapper.py +22 -0
- package/lib/darkarts/validation/config.py +257 -0
- package/lib/darkarts/validation/performance.py +412 -0
- package/lib/darkarts/validation/performance_wrapper.py +37 -0
- package/lib/darkarts/validation/semantic.py +461 -0
- package/lib/darkarts/validation/semantic_wrapper.py +77 -0
- package/lib/darkarts/validation/test_validation.py +160 -0
- package/lib/darkarts/validation/types.py +97 -0
- package/lib/darkarts/validation/watch.py +239 -0
- package/package.json +19 -6
- package/voodocs_cli.py +28 -0
- package/cli.py +0 -1646
- package/lib/darkarts/cli.py +0 -128
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""@darkarts
|
|
2
|
+
⊢cli:validate
|
|
3
|
+
∂{click,pathlib,typing,sys,darkarts,json}
|
|
4
|
+
⚠{python≥3.7,click≥8.0,rich≥10.0}
|
|
5
|
+
⊨{∀validation→executed,∀result→displayed}
|
|
6
|
+
🔒{read-only:validation}
|
|
7
|
+
⚡{O(n²)|n=files,nested-iteration-for-display}
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
VooDocs CLI - Validate Command
|
|
12
|
+
|
|
13
|
+
Validates @darkarts annotations in Python files.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import click
|
|
17
|
+
import sys
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import List, Optional
|
|
20
|
+
|
|
21
|
+
# Import validation module
|
|
22
|
+
import sys
|
|
23
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
24
|
+
from darkarts.validation import SemanticValidator, PerformanceTracker
|
|
25
|
+
from darkarts.validation.types import ValidationResult, PerformanceResult
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@click.command()
|
|
29
|
+
@click.argument('path', type=click.Path(exists=True))
|
|
30
|
+
@click.option(
|
|
31
|
+
'-r', '--recursive',
|
|
32
|
+
is_flag=True,
|
|
33
|
+
help='Recursively validate all Python files in directory'
|
|
34
|
+
)
|
|
35
|
+
@click.option(
|
|
36
|
+
'--deps/--no-deps',
|
|
37
|
+
default=True,
|
|
38
|
+
help='Validate dependencies (default: enabled)'
|
|
39
|
+
)
|
|
40
|
+
@click.option(
|
|
41
|
+
'--perf/--no-perf',
|
|
42
|
+
default=True,
|
|
43
|
+
help='Validate performance claims (default: enabled)'
|
|
44
|
+
)
|
|
45
|
+
@click.option(
|
|
46
|
+
'--strict',
|
|
47
|
+
is_flag=True,
|
|
48
|
+
help='Exit with error code if any validation fails'
|
|
49
|
+
)
|
|
50
|
+
@click.option(
|
|
51
|
+
'--format',
|
|
52
|
+
type=click.Choice(['text', 'json', 'html']),
|
|
53
|
+
default='text',
|
|
54
|
+
help='Output format (default: text)'
|
|
55
|
+
)
|
|
56
|
+
@click.option(
|
|
57
|
+
'--output',
|
|
58
|
+
type=click.Path(),
|
|
59
|
+
help='Output file (default: stdout)'
|
|
60
|
+
)
|
|
61
|
+
@click.option(
|
|
62
|
+
'--exclude',
|
|
63
|
+
multiple=True,
|
|
64
|
+
help='Exclude patterns (can be used multiple times)'
|
|
65
|
+
)
|
|
66
|
+
@click.option(
|
|
67
|
+
'--fix',
|
|
68
|
+
is_flag=True,
|
|
69
|
+
help='Automatically fix issues (preview with --dry-run)'
|
|
70
|
+
)
|
|
71
|
+
@click.option(
|
|
72
|
+
'--dry-run',
|
|
73
|
+
is_flag=True,
|
|
74
|
+
help='Show what would be fixed without making changes'
|
|
75
|
+
)
|
|
76
|
+
def validate(
|
|
77
|
+
path: str,
|
|
78
|
+
recursive: bool,
|
|
79
|
+
deps: bool,
|
|
80
|
+
perf: bool,
|
|
81
|
+
strict: bool,
|
|
82
|
+
format: str,
|
|
83
|
+
output: Optional[str],
|
|
84
|
+
exclude: tuple,
|
|
85
|
+
fix: bool,
|
|
86
|
+
dry_run: bool,
|
|
87
|
+
):
|
|
88
|
+
"""
|
|
89
|
+
Validate @darkarts annotations in Python files.
|
|
90
|
+
|
|
91
|
+
Examples:
|
|
92
|
+
|
|
93
|
+
# Validate a single file
|
|
94
|
+
voodocs validate myfile.py
|
|
95
|
+
|
|
96
|
+
# Validate all files in a directory
|
|
97
|
+
voodocs validate lib/ -r
|
|
98
|
+
|
|
99
|
+
# Validate with strict mode (exit code 1 on failure)
|
|
100
|
+
voodocs validate lib/ -r --strict
|
|
101
|
+
|
|
102
|
+
# Validate only dependencies
|
|
103
|
+
voodocs validate lib/ -r --no-perf
|
|
104
|
+
|
|
105
|
+
# Output as JSON
|
|
106
|
+
voodocs validate lib/ -r --format json --output report.json
|
|
107
|
+
|
|
108
|
+
# Auto-fix issues
|
|
109
|
+
voodocs validate lib/ -r --fix
|
|
110
|
+
"""
|
|
111
|
+
path_obj = Path(path)
|
|
112
|
+
|
|
113
|
+
# Print header
|
|
114
|
+
click.echo(f"Validating: {path}")
|
|
115
|
+
click.echo("━" * 60)
|
|
116
|
+
click.echo()
|
|
117
|
+
|
|
118
|
+
# Collect results
|
|
119
|
+
semantic_results: List[ValidationResult] = []
|
|
120
|
+
performance_results: List[PerformanceResult] = []
|
|
121
|
+
|
|
122
|
+
# Run semantic validation
|
|
123
|
+
if deps:
|
|
124
|
+
click.echo("Running semantic validation...")
|
|
125
|
+
validator = SemanticValidator()
|
|
126
|
+
|
|
127
|
+
if path_obj.is_file():
|
|
128
|
+
semantic_results = [validator.validate_file(path_obj)]
|
|
129
|
+
else:
|
|
130
|
+
semantic_results = validator.validate_directory(path_obj, recursive=recursive)
|
|
131
|
+
|
|
132
|
+
click.echo(f"✓ Validated {len(semantic_results)} files")
|
|
133
|
+
click.echo()
|
|
134
|
+
|
|
135
|
+
# Run performance validation
|
|
136
|
+
if perf:
|
|
137
|
+
click.echo("Running performance validation...")
|
|
138
|
+
tracker = PerformanceTracker()
|
|
139
|
+
|
|
140
|
+
if path_obj.is_file():
|
|
141
|
+
performance_results = [tracker.analyze_file(path_obj)]
|
|
142
|
+
else:
|
|
143
|
+
performance_results = tracker.analyze_directory(path_obj, recursive=recursive)
|
|
144
|
+
|
|
145
|
+
click.echo(f"✓ Analyzed {len(performance_results)} files")
|
|
146
|
+
click.echo()
|
|
147
|
+
|
|
148
|
+
# Display results based on format
|
|
149
|
+
if format == 'text':
|
|
150
|
+
display_text_results(semantic_results, performance_results)
|
|
151
|
+
elif format == 'json':
|
|
152
|
+
display_json_results(semantic_results, performance_results, output)
|
|
153
|
+
elif format == 'html':
|
|
154
|
+
display_html_results(semantic_results, performance_results, output)
|
|
155
|
+
|
|
156
|
+
# Summary
|
|
157
|
+
click.echo()
|
|
158
|
+
click.echo("━" * 60)
|
|
159
|
+
|
|
160
|
+
total_files = len(semantic_results) if semantic_results else len(performance_results)
|
|
161
|
+
valid_semantic = sum(1 for r in semantic_results if r.is_valid) if semantic_results else 0
|
|
162
|
+
valid_perf = sum(1 for r in performance_results if r.is_valid) if performance_results else 0
|
|
163
|
+
|
|
164
|
+
if deps and perf:
|
|
165
|
+
valid = min(valid_semantic, valid_perf)
|
|
166
|
+
invalid = total_files - valid
|
|
167
|
+
elif deps:
|
|
168
|
+
valid = valid_semantic
|
|
169
|
+
invalid = total_files - valid
|
|
170
|
+
elif perf:
|
|
171
|
+
valid = valid_perf
|
|
172
|
+
invalid = total_files - valid
|
|
173
|
+
else:
|
|
174
|
+
valid = total_files
|
|
175
|
+
invalid = 0
|
|
176
|
+
|
|
177
|
+
click.echo(f"Total: {total_files} files")
|
|
178
|
+
click.echo(f"Valid: {valid} ({valid/total_files*100:.1f}%)" if total_files > 0 else "Valid: 0")
|
|
179
|
+
click.echo(f"Invalid: {invalid} ({invalid/total_files*100:.1f}%)" if total_files > 0 else "Invalid: 0")
|
|
180
|
+
click.echo("━" * 60)
|
|
181
|
+
|
|
182
|
+
# Exit code
|
|
183
|
+
if strict and invalid > 0:
|
|
184
|
+
click.echo()
|
|
185
|
+
click.echo("❌ Validation failed (strict mode)", err=True)
|
|
186
|
+
sys.exit(1)
|
|
187
|
+
elif invalid > 0:
|
|
188
|
+
click.echo()
|
|
189
|
+
click.echo("💡 Run 'voodocs fix' to automatically fix issues")
|
|
190
|
+
else:
|
|
191
|
+
click.echo()
|
|
192
|
+
click.echo("✅ All validations passed!")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def display_text_results(
|
|
196
|
+
semantic_results: List[ValidationResult],
|
|
197
|
+
performance_results: List[PerformanceResult]
|
|
198
|
+
):
|
|
199
|
+
"""Display results in text format."""
|
|
200
|
+
|
|
201
|
+
# Display semantic results
|
|
202
|
+
if semantic_results:
|
|
203
|
+
click.echo("Semantic Validation Results:")
|
|
204
|
+
click.echo()
|
|
205
|
+
|
|
206
|
+
for result in semantic_results:
|
|
207
|
+
if result.is_valid:
|
|
208
|
+
click.echo(f"✅ {result.file_path}")
|
|
209
|
+
else:
|
|
210
|
+
click.echo(f"❌ {result.file_path}")
|
|
211
|
+
|
|
212
|
+
if result.missing_deps:
|
|
213
|
+
click.echo(f" Missing from ∂{{}}: {', '.join(sorted(result.missing_deps))}")
|
|
214
|
+
|
|
215
|
+
if result.extra_deps:
|
|
216
|
+
click.echo(f" Extra in ∂{{}}: {', '.join(sorted(result.extra_deps))}")
|
|
217
|
+
|
|
218
|
+
if result.errors:
|
|
219
|
+
for error in result.errors:
|
|
220
|
+
click.echo(f" Error: {error}")
|
|
221
|
+
|
|
222
|
+
if result.warnings:
|
|
223
|
+
for warning in result.warnings:
|
|
224
|
+
click.echo(f" Warning: {warning}")
|
|
225
|
+
|
|
226
|
+
click.echo()
|
|
227
|
+
|
|
228
|
+
# Display performance results
|
|
229
|
+
if performance_results:
|
|
230
|
+
click.echo("Performance Validation Results:")
|
|
231
|
+
click.echo()
|
|
232
|
+
|
|
233
|
+
for result in performance_results:
|
|
234
|
+
if result.is_valid:
|
|
235
|
+
click.echo(f"✅ {result.file_path}")
|
|
236
|
+
if hasattr(result, 'claimed_complexity') and result.claimed_complexity:
|
|
237
|
+
click.echo(f" Complexity: {result.claimed_complexity}")
|
|
238
|
+
else:
|
|
239
|
+
click.echo(f"❌ {result.file_path}")
|
|
240
|
+
if hasattr(result, 'claimed_complexity') and result.claimed_complexity:
|
|
241
|
+
click.echo(f" Claimed: {result.claimed_complexity}")
|
|
242
|
+
if hasattr(result, 'static_analysis') and result.static_analysis:
|
|
243
|
+
click.echo(f" Static Analysis: {result.static_analysis}")
|
|
244
|
+
|
|
245
|
+
if hasattr(result, 'warnings') and result.warnings:
|
|
246
|
+
for warning in result.warnings:
|
|
247
|
+
click.echo(f" Warning: {warning}")
|
|
248
|
+
|
|
249
|
+
if hasattr(result, 'suggestions') and result.suggestions:
|
|
250
|
+
for suggestion in result.suggestions:
|
|
251
|
+
click.echo(f" Suggestion: {suggestion}")
|
|
252
|
+
|
|
253
|
+
click.echo()
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def display_json_results(
|
|
257
|
+
semantic_results: List[ValidationResult],
|
|
258
|
+
performance_results: List[PerformanceResult],
|
|
259
|
+
output: Optional[str]
|
|
260
|
+
):
|
|
261
|
+
"""Display results in JSON format."""
|
|
262
|
+
import json
|
|
263
|
+
|
|
264
|
+
# Convert results to dicts
|
|
265
|
+
semantic_dicts = []
|
|
266
|
+
for r in semantic_results:
|
|
267
|
+
semantic_dicts.append({
|
|
268
|
+
"file_path": r.file_path,
|
|
269
|
+
"is_valid": r.is_valid,
|
|
270
|
+
"missing_deps": list(r.missing_deps) if hasattr(r, 'missing_deps') else [],
|
|
271
|
+
"extra_deps": list(r.extra_deps) if hasattr(r, 'extra_deps') else [],
|
|
272
|
+
"errors": r.errors if hasattr(r, 'errors') else [],
|
|
273
|
+
"warnings": r.warnings if hasattr(r, 'warnings') else [],
|
|
274
|
+
"suggestions": r.suggestions if hasattr(r, 'suggestions') else [],
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
# Performance results
|
|
278
|
+
perf_dicts = []
|
|
279
|
+
for r in performance_results:
|
|
280
|
+
perf_dicts.append({
|
|
281
|
+
"file_path": r.file_path,
|
|
282
|
+
"is_valid": r.is_valid,
|
|
283
|
+
"claimed_complexity": str(r.claimed_complexity) if hasattr(r, 'claimed_complexity') else None,
|
|
284
|
+
"warnings": r.warnings if hasattr(r, 'warnings') else [],
|
|
285
|
+
"suggestions": r.suggestions if hasattr(r, 'suggestions') else [],
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
data = {
|
|
289
|
+
"semantic": semantic_dicts,
|
|
290
|
+
"performance": perf_dicts,
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
json_str = json.dumps(data, indent=2)
|
|
294
|
+
|
|
295
|
+
if output:
|
|
296
|
+
Path(output).write_text(json_str)
|
|
297
|
+
click.echo(f"Results written to: {output}")
|
|
298
|
+
else:
|
|
299
|
+
click.echo(json_str)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def display_html_results(
|
|
303
|
+
semantic_results: List[ValidationResult],
|
|
304
|
+
performance_results: List[PerformanceResult],
|
|
305
|
+
output: Optional[str]
|
|
306
|
+
):
|
|
307
|
+
"""Display results in HTML format."""
|
|
308
|
+
html = """
|
|
309
|
+
<!DOCTYPE html>
|
|
310
|
+
<html>
|
|
311
|
+
<head>
|
|
312
|
+
<title>VooDocs Validation Report</title>
|
|
313
|
+
<style>
|
|
314
|
+
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
315
|
+
h1 { color: #333; }
|
|
316
|
+
.valid { color: green; }
|
|
317
|
+
.invalid { color: red; }
|
|
318
|
+
.file { margin: 10px 0; padding: 10px; border: 1px solid #ddd; }
|
|
319
|
+
</style>
|
|
320
|
+
</head>
|
|
321
|
+
<body>
|
|
322
|
+
<h1>VooDocs Validation Report</h1>
|
|
323
|
+
|
|
324
|
+
<h2>Semantic Validation</h2>
|
|
325
|
+
"""
|
|
326
|
+
|
|
327
|
+
for result in semantic_results:
|
|
328
|
+
status = "valid" if result.is_valid else "invalid"
|
|
329
|
+
html += f'<div class="file {status}">\n'
|
|
330
|
+
html += f'<strong>{result.file_path}</strong>: {"✅ Valid" if result.is_valid else "❌ Invalid"}<br>\n'
|
|
331
|
+
|
|
332
|
+
if not result.is_valid:
|
|
333
|
+
if result.missing_deps:
|
|
334
|
+
html += f'Missing: {", ".join(sorted(result.missing_deps))}<br>\n'
|
|
335
|
+
if result.extra_deps:
|
|
336
|
+
html += f'Extra: {", ".join(sorted(result.extra_deps))}<br>\n'
|
|
337
|
+
|
|
338
|
+
html += '</div>\n'
|
|
339
|
+
|
|
340
|
+
html += """
|
|
341
|
+
<h2>Performance Validation</h2>
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
for result in performance_results:
|
|
345
|
+
status = "valid" if result.is_valid else "invalid"
|
|
346
|
+
html += f'<div class="file {status}">\n'
|
|
347
|
+
html += f'<strong>{result.file_path}</strong>: {"✅ Valid" if result.is_valid else "❌ Invalid"}<br>\n'
|
|
348
|
+
html += f'Claimed: {result.claimed_complexity}<br>\n'
|
|
349
|
+
|
|
350
|
+
if not result.is_valid:
|
|
351
|
+
html += f'Actual: {result.actual_complexity}<br>\n'
|
|
352
|
+
|
|
353
|
+
html += '</div>\n'
|
|
354
|
+
|
|
355
|
+
html += """
|
|
356
|
+
</body>
|
|
357
|
+
</html>
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
if output:
|
|
361
|
+
Path(output).write_text(html)
|
|
362
|
+
click.echo(f"Results written to: {output}")
|
|
363
|
+
else:
|
|
364
|
+
click.echo(html)
|
package/lib/darkarts/__init__.py
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""@darkarts
|
|
2
|
+
⊢init:lib.darkarts.package
|
|
3
|
+
∂{}
|
|
4
|
+
⚠{python≥3.7}
|
|
5
|
+
⊨{∀import→exports-available,namespace:clean,¬side-effects-on-import}
|
|
6
|
+
🔒{pure-init,¬io,¬network,¬exec}
|
|
7
|
+
⚡{O(1):import-time}
|
|
8
|
+
|
|
9
|
+
Package initialization for lib.darkarts.
|
|
3
10
|
|
|
4
|
-
|
|
5
|
-
and computational reality, allowing AI to express solutions in mathematics
|
|
6
|
-
while getting executable results without writing code.
|
|
11
|
+
Module exports and namespace configuration.
|
|
7
12
|
"""
|
|
8
13
|
|
|
14
|
+
|
|
9
15
|
__version__ = "0.1.0-alpha"
|
|
10
16
|
__author__ = "Vooodooo"
|
|
11
17
|
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""@darkarts
|
|
2
|
+
⊢init:annotations.package
|
|
3
|
+
∂{}
|
|
4
|
+
⚠{python≥3.7}
|
|
5
|
+
⊨{∀import→exports-available,namespace:clean,¬side-effects-on-import}
|
|
6
|
+
🔒{pure-init,¬io,¬network,¬exec}
|
|
7
|
+
⚡{O(1):import-time}
|
|
8
|
+
|
|
9
|
+
Package initialization for annotations.
|
|
3
10
|
|
|
4
|
-
|
|
11
|
+
Module exports and namespace configuration.
|
|
5
12
|
"""
|
|
6
13
|
|
|
14
|
+
|
|
7
15
|
from .types import (
|
|
8
16
|
ParsedAnnotations,
|
|
9
17
|
ModuleAnnotation,
|
|
@@ -209,7 +209,7 @@ class DarkArtsTranslator:
|
|
|
209
209
|
Returns:
|
|
210
210
|
Symbolic notation
|
|
211
211
|
"""
|
|
212
|
-
result = text
|
|
212
|
+
result = text
|
|
213
213
|
|
|
214
214
|
# Replace English phrases with symbols
|
|
215
215
|
# Sort by length (longest first) to avoid partial matches
|
|
@@ -217,7 +217,14 @@ class DarkArtsTranslator:
|
|
|
217
217
|
key=lambda x: len(x[0]), reverse=True)
|
|
218
218
|
|
|
219
219
|
for english, symbol in phrases:
|
|
220
|
-
|
|
220
|
+
# Use word boundaries to avoid mid-word replacements
|
|
221
|
+
# This prevents "or" in "authenticated" from being replaced
|
|
222
|
+
pattern = r'\b' + re.escape(english) + r'\b'
|
|
223
|
+
try:
|
|
224
|
+
result = re.sub(pattern, symbol, result, flags=re.IGNORECASE)
|
|
225
|
+
except re.error:
|
|
226
|
+
# Fallback for patterns that don't work with word boundaries
|
|
227
|
+
pass
|
|
221
228
|
|
|
222
229
|
return result
|
|
223
230
|
|
|
@@ -311,15 +318,35 @@ class DarkArtsTranslator:
|
|
|
311
318
|
symbolic = [self._convert_invariant(inv) for inv in invariants]
|
|
312
319
|
lines.append(f"⊨{{{','.join(symbolic)}}}")
|
|
313
320
|
|
|
321
|
+
# Preconditions
|
|
322
|
+
if 'preconditions' in voodocs_dict:
|
|
323
|
+
preconditions = voodocs_dict['preconditions']
|
|
324
|
+
if isinstance(preconditions, list):
|
|
325
|
+
symbolic = [self._convert_invariant(pre) for pre in preconditions]
|
|
326
|
+
lines.append(f"⊳{{{','.join(symbolic)}}}")
|
|
327
|
+
|
|
328
|
+
# Postconditions
|
|
329
|
+
if 'postconditions' in voodocs_dict:
|
|
330
|
+
postconditions = voodocs_dict['postconditions']
|
|
331
|
+
if isinstance(postconditions, list):
|
|
332
|
+
symbolic = [self._convert_invariant(post) for post in postconditions]
|
|
333
|
+
lines.append(f"⊲{{{','.join(symbolic)}}}")
|
|
334
|
+
|
|
314
335
|
# Security
|
|
315
|
-
if 'security_model' in voodocs_dict:
|
|
316
|
-
security =
|
|
336
|
+
if 'security_model' in voodocs_dict or 'security_implications' in voodocs_dict:
|
|
337
|
+
security = voodocs_dict.get('security_model') or voodocs_dict.get('security_implications')
|
|
338
|
+
if isinstance(security, list):
|
|
339
|
+
security = ', '.join(security)
|
|
340
|
+
security = self._simplify_text(str(security))
|
|
317
341
|
lines.append(f"🔒{{{security}}}")
|
|
318
342
|
|
|
319
|
-
# Performance
|
|
343
|
+
# Performance/Complexity
|
|
320
344
|
if 'performance_model' in voodocs_dict:
|
|
321
345
|
perf = voodocs_dict['performance_model']
|
|
322
346
|
lines.append(f"⚡{{{perf}}}")
|
|
347
|
+
elif 'complexity' in voodocs_dict:
|
|
348
|
+
complexity = voodocs_dict['complexity']
|
|
349
|
+
lines.append(f"⚡{{{complexity}}}")
|
|
323
350
|
|
|
324
351
|
lines.append('"""')
|
|
325
352
|
return '\n'.join(lines)
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""@darkarts
|
|
2
|
+
⊢annotation-types:annotations.data-structures
|
|
3
|
+
∂{dataclasses,typing,enum}
|
|
4
|
+
⚠{python≥3.7}
|
|
5
|
+
⊨{∀dataclass:valid-schema,∀enum:valid-values,∀annotation:complete-representation,serializable:to-dict,multi-language:supported}
|
|
6
|
+
🔒{pure-data,¬io,¬side-effects,¬exec}
|
|
7
|
+
⚡{O(1):all-ops,lightweight-dataclasses}
|
|
8
|
+
|
|
2
9
|
DarkArts Annotation Types
|
|
3
10
|
|
|
4
|
-
Data structures for
|
|
11
|
+
Data structures for parsed @darkarts/@voodocs annotations with:
|
|
12
|
+
- Annotation types (function, method, class, module)
|
|
13
|
+
- Language support (Python, TypeScript, JavaScript, Java, C++, C#, Go, Rust)
|
|
14
|
+
- Complexity annotations (time, space, best/worst/average case)
|
|
15
|
+
- State transitions (from_state → to_state with conditions)
|
|
16
|
+
- Error cases (condition, error_type, description)
|
|
17
|
+
- Structured representations (FunctionAnnotation, ClassAnnotation, ModuleAnnotation)
|
|
5
18
|
"""
|
|
6
19
|
|
|
7
20
|
from dataclasses import dataclass, field
|