mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
Merge branch 'main' into testgen-jit-iter
This commit is contained in:
commit
14feee119f
1 changed files with 87 additions and 8 deletions
|
|
@ -5,30 +5,109 @@ Uses Node.js for validation when available, with a basic regex fallback.
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from functools import lru_cache
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import tree_sitter_javascript
|
||||
import tree_sitter_typescript
|
||||
from tree_sitter import Language, Parser
|
||||
|
||||
from aiservice.common.markdown_utils import split_markdown_code
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tree_sitter import Node
|
||||
|
||||
js_parser = Parser(Language(tree_sitter_javascript.language()))
|
||||
|
||||
ts_parser = Parser(Language(tree_sitter_typescript.language_typescript()))
|
||||
|
||||
|
||||
@lru_cache(maxsize=200)
|
||||
def _validate(code: str, lang: str) -> bool:
|
||||
parser = js_parser if lang == "js" else ts_parser
|
||||
tree = parser.parse(code.encode("utf8"))
|
||||
return not tree.root_node.has_error
|
||||
|
||||
|
||||
def _find_error_location(code: str, lang: str) -> str | None:
|
||||
"""Find the location of the first syntax error in the code."""
|
||||
parser = js_parser if lang == "js" else ts_parser
|
||||
tree = parser.parse(code.encode("utf8"))
|
||||
if not tree.root_node.has_error:
|
||||
return None
|
||||
|
||||
def find_error(node: Node) -> tuple[int, int] | None:
|
||||
if node.type == "ERROR":
|
||||
return node.start_point
|
||||
for child in node.children:
|
||||
result = find_error(child)
|
||||
if result:
|
||||
return result
|
||||
return None
|
||||
|
||||
error_point = find_error(tree.root_node)
|
||||
if error_point:
|
||||
line, col = error_point
|
||||
lines = code.split("\n")
|
||||
if line < len(lines):
|
||||
error_line = lines[line]
|
||||
return f"line {line + 1}, col {col}: {error_line[:80]}"
|
||||
return f"line {line + 1}, col {col}"
|
||||
return "unknown location"
|
||||
|
||||
|
||||
@lru_cache(maxsize=100)
|
||||
def validate_javascript_syntax(code: str) -> tuple[bool, str | None]:
|
||||
tree = js_parser.parse(bytes(code, "utf8"))
|
||||
has_error = tree.root_node.has_error
|
||||
if has_error:
|
||||
return False, "Invalid syntax"
|
||||
if code.strip().startswith("```"):
|
||||
# markdown code block
|
||||
file_to_code = split_markdown_code(code, "javascript")
|
||||
if not file_to_code:
|
||||
msg = f"No JavaScript code blocks found in markdown. Code starts with: {code[:100]!r}"
|
||||
logging.warning(msg)
|
||||
# Fall through to validate the raw code
|
||||
else:
|
||||
for filepath, _code in file_to_code.items():
|
||||
valid = _validate(_code, "js")
|
||||
if not valid:
|
||||
error_loc = _find_error_location(_code, "js")
|
||||
msg = f"Invalid JavaScript syntax in {filepath}: {error_loc}. Code snippet: {_code[:200]!r}"
|
||||
logging.error(msg)
|
||||
return False, f"Invalid syntax at {error_loc}"
|
||||
return True, None
|
||||
|
||||
valid = _validate(code, "js")
|
||||
if not valid:
|
||||
error_loc = _find_error_location(code, "js")
|
||||
msg = f"Invalid JavaScript syntax: {error_loc}. Code snippet: {code[:200]!r}"
|
||||
logging.error(msg)
|
||||
return False, f"Invalid syntax at {error_loc}"
|
||||
return True, None
|
||||
|
||||
|
||||
@lru_cache(maxsize=100)
|
||||
def validate_typescript_syntax(code: str) -> tuple[bool, str | None]:
|
||||
tree = ts_parser.parse(bytes(code, "utf8"))
|
||||
has_error = tree.root_node.has_error
|
||||
if has_error:
|
||||
return False, "Invalid syntax"
|
||||
if code.strip().startswith("```"):
|
||||
# markdown code block
|
||||
file_to_code = split_markdown_code(code, "typescript")
|
||||
if not file_to_code:
|
||||
msg = f"No TypeScript code blocks found in markdown. Code starts with: {code[:100]!r}"
|
||||
logging.warning(msg)
|
||||
# Fall through to validate the raw code
|
||||
else:
|
||||
for filepath, _code in file_to_code.items():
|
||||
valid = _validate(_code, "ts")
|
||||
if not valid:
|
||||
error_loc = _find_error_location(_code, "ts")
|
||||
msg = f"Invalid TypeScript syntax in {filepath}: {error_loc}. Code snippet: {_code[:200]!r}"
|
||||
logging.error(msg)
|
||||
return False, f"Invalid syntax at {error_loc}"
|
||||
return True, None
|
||||
|
||||
valid = _validate(code, "ts")
|
||||
if not valid:
|
||||
error_loc = _find_error_location(code, "ts")
|
||||
msg = f"Invalid TypeScript syntax: {error_loc}. Code snippet: {code[:200]!r}"
|
||||
logging.error(msg)
|
||||
return False, f"Invalid syntax at {error_loc}"
|
||||
return True, None
|
||||
|
|
|
|||
Loading…
Reference in a new issue