1
1
mirror of https://github.com/KenanZhu/AutoLibrary.git synced 2026-06-17 23:13:03 +08:00

refactor(autoscript): 公开 splitTopLevel 并导出常量,消除冗余委托与重复变量

This commit is contained in:
2026-05-18 16:01:10 +08:00
parent 6cf182c8c8
commit c038c8005d
3 changed files with 39 additions and 49 deletions
+11 -4
View File
@@ -33,7 +33,7 @@ from .ASTokenizer import (
)
__all__ = ["execute", "addTargetVar"]
__all__ = ["execute", "addTargetVar", "splitTopLevel"]
# Engine state
@@ -69,7 +69,7 @@ _RE_CUR_DATE_OFFSET = re.compile(r"^CURRENT_DATE\s*\+\s*(\d+)$", re.IGNORECASE)
_RE_CUR_TIME_OFFSET = re.compile(r"^CURRENT_TIME\s*\+\s*(\d+)$", re.IGNORECASE)
def _splitTopLevel(
def splitTopLevel(
text: str,
delimiter: str
) -> list:
@@ -281,13 +281,13 @@ def _evaluateCondition(
s = condition_str.strip()
if not s:
return False
or_parts = _splitTopLevel(s, ".OR.")
or_parts = splitTopLevel(s, ".OR.")
if len(or_parts) > 1:
return any(
_evaluateCondition(p.strip(), target_data, line)
for p in or_parts
)
and_parts = _splitTopLevel(s, ".AND.")
and_parts = splitTopLevel(s, ".AND.")
if len(and_parts) > 1:
return all(
_evaluateCondition(p.strip(), target_data, line)
@@ -466,12 +466,14 @@ class _EngineExecutor(NodeVisitor):
return self._cur_line
def _incLine(
self
):
self._cur_line += 1
def visitScript(
self,
_node: Script
@@ -480,6 +482,7 @@ class _EngineExecutor(NodeVisitor):
for child in _node.body:
child.accept(self)
def visitIf(
self,
_node: IfNode
@@ -506,6 +509,7 @@ class _EngineExecutor(NodeVisitor):
for child in _node.else_body:
child.accept(self)
def visitSet(
self,
_node: SetNode
@@ -515,6 +519,7 @@ class _EngineExecutor(NodeVisitor):
full_line = f"SET {_node.target} = {_node.value}"
_executeSet(full_line, self._target_data, self._line)
def visitOp(
self,
_node: OpNode
@@ -525,6 +530,7 @@ class _EngineExecutor(NodeVisitor):
full_line = f"{_node.target} .{op_upper}. {_node.value}"
_executeOperation(full_line, self._target_data, self._line)
def visitPass(
self,
_node: PassNode
@@ -532,6 +538,7 @@ class _EngineExecutor(NodeVisitor):
self._incLine()
def visitUnrecog(
self,
_node: UnrecogNode
+16 -33
View File
@@ -17,7 +17,7 @@ from datetime import (
from .ASObject import ASObject
__all__ = ["ASOperator"]
__all__ = ["ASOperator", "ARITH_TYPES", "COMPARISON_OPERATORS"]
class ASOperator:
@@ -96,12 +96,11 @@ class ASOperator:
target_val = target.getValue(target_data)
if target_val is None:
raise ValueError(f"'{target.name}' 的值为空,无法进行运算")
if op == ".ADD.":
cls._arithAdd(target, target_val, operand, target_data)
elif op == ".SUB.":
cls._arithSub(target, target_val, operand, target_data)
else:
op_name = "ADD" if op == ".ADD." else "SUB" if op == ".SUB." else None
if op_name is None:
raise ValueError(f"不支持的操作 '{op}'")
sign = 1 if op == ".ADD." else -1
cls._arithBinary(target, target_val, operand, target_data, sign, op_name)
@classmethod
def _arithBinary(
@@ -110,13 +109,13 @@ class ASOperator:
target_val,
operand: ASObject,
target_data: dict,
sign: int
sign: int,
op_name: str = ""
):
"""Apply ADD (sign=1) or SUB (sign=-1) per type."""
"""Apply arithmetic per type."""
tp = target.var_type
raw_op = operand._value
op_name = "ADD" if sign == 1 else "SUB"
if tp == "Date":
if not isinstance(target_val, date):
@@ -129,35 +128,13 @@ class ASOperator:
dt = datetime.combine(datetime.today(), target_val) + delta
new_val = dt.time()
elif tp == "Int":
new_val = int(target_val) + int(raw_op) * sign
new_val = int(target_val) + int(raw_op)*sign
elif tp == "Float":
new_val = float(target_val) + float(raw_op) * sign
new_val = float(target_val) + float(raw_op)*sign
else:
raise ValueError(f"'{tp}' 类型不支持 {op_name} 操作")
target.setValue(new_val, target_data)
@classmethod
def _arithAdd(
cls,
target: ASObject,
target_val,
operand: ASObject,
target_data: dict
):
"""Dispatch ADD per type."""
cls._arithBinary(target, target_val, operand, target_data, 1)
@classmethod
def _arithSub(
cls,
target: ASObject,
target_val,
operand: ASObject,
target_data: dict
):
"""Dispatch SUB per type."""
cls._arithBinary(target, target_val, operand, target_data, -1)
@classmethod
def compare(
cls,
@@ -206,3 +183,9 @@ class ASOperator:
f"无法比较 '{left.name}' ({left.var_type}) "
f"'{right.name}' ({right.var_type})"
)
# Public constants
# may be used by the GUI orchestration dialog.
ARITH_TYPES = ASOperator._ARITH_TYPES
COMPARISON_OPERATORS = set(ASOperator._COMPARE.keys())
+12 -12
View File
@@ -14,13 +14,16 @@ from autoscript.ASTokenizer import (
from autoscript.ASEngine import (
execute,
addTargetVar,
splitTopLevel,
)
from autoscript.ASObject import _META_VARS as META_VARS
from autoscript.ASObserver import ParsingObserver
__all__ = [
"execute",
"addTargetVar",
"splitTopLevel",
"registerDefaultTargetVars",
"buildMockTargetData",
"META_VARS",
@@ -35,18 +38,6 @@ __all__ = [
"ParsingObserver",
]
# All variables available to scripts (display_name -> (name, type)).
# This mirrors the old AutoScriptEngine.VARIABLE_META for backward
# compatibility in the UI orchestration dialog.
ALL_VARIABLES: dict = {
"用户名": ("USERNAME", "String"),
"用户启用": ("USER_ENABLE", "Boolean"),
"预约日期": ("RESERVE_DATE", "Date"),
"预约开始时间": ("RESERVE_BEGIN_TIME", "Time"),
"预约结束时间": ("RESERVE_END_TIME", "Time"),
"当前时间": ("CURRENT_TIME", "Time"),
"当前日期": ("CURRENT_DATE", "Date"),
}
# Key paths into target_data dict for each target variable.
# (name, type, key_path, display_name)
@@ -57,6 +48,15 @@ _TARGET_VAR_DEFS = [
("RESERVE_BEGIN_TIME", "Time", ["reserve_info", "begin_time", "time"], "预约开始时间"),
("RESERVE_END_TIME", "Time", ["reserve_info", "end_time", "time"], "预约结束时间"),
]
# All variables (display_name -> (name, type)), derived from target vars + meta vars.
ALL_VARIABLES = {
display_name: (name, var_type)
for name, var_type, _, display_name in _TARGET_VAR_DEFS
} | {
obj.display_name: (obj.name, obj.var_type)
for obj in META_VARS.values()
}
_MOCK_TYPE_VALUES = {
"String": "__mock__",
"Boolean": True,