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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user